台頭

Nuxeo サーバの性能を改善し、これまで以上に最新化と効率化を図る中、当社は今回、Kotlin 言語の台頭に注目しました。

Nuxeo KotlinKotlin は、Java 仮想マシン上で実行され、JetBrains作成の JavaScript ソースコードにコンパイルできる静的型付けプログラミング言語です。この言語は、Java「よりも優れた」インダストリアル強度のオブジェクト指向言語として設計されていますが、Java コードとの相互運用性を完全に維持しています。そのため、組織は Java から Kotlin への移行を徐々に進めることが可能です。

あらゆる Android アプリを Kotlin で記述できるようにすることを Google が発表するなど、この言語は第一級のプログラミング言語となっています。

Nuxeo バンドルを Kotlin で開発できるようになったことを、ここに喜んで発表いたします!

Kotlin と Java

Kotlin は Java コードと完全に相互運用可能です。そのため、Kotlin と Java の両方を 1 つのバンドルにコンパイルして、連携させることができます!

仕組み

プロジェクト構造

どのMavenプロジェクト構造もそうであるように、Kotlin バンドルは Nuxeo Java バンドルと似ています。ただし、Kotlin コード用に新しいフォルダ「kotlin」を「java」の代わりに使用する点は異なります。

├── pom.xml
└── src
    ├── main
    │   ├── kotlin
    │   │   └── org
    │   │       └── nuxeo
    │   │           └── sample
    │   └── resources
    │       ├── META-INF
    │       └── OSGI-INF
    └── test
        └── org
            └── nuxeo
                └── kotlin
                    └── sample

もちろん、Java と Kotlin の両方を同じバンドルに混在させることが可能です!

├── pom.xml
└── src
    ├── main
    │   ├── kotlin
    │   │   └── org
    │   │       └── nuxeo
    │   │           └── sample
    |   ├── java
    |   |   ├── org......
    │   └── resources

最初の Kotlin バンドル

それを行い、かつ、プロジェクトのブートストラップを容易に行えるよう、Nuxeo CLIを使用して専用のテンプレートを既に作成済みです。パッケージとサンプルオペレーションを使用して新しいバンドルを作成しましょう。

# Ensure to have the latest version nuxeo update

# You can create an empty bundle using # nuxeo bootstrap kotlin-module # But, following this blog, we are going to create a more complete example mkdir kotlin-sample && cd $_ nuxeo bootstrap kotlin-operation package

下記は答えの例です。これにこだわることなく、クリエイティブに答えていただいてかまいません。

info You'll be prompted for generation of: info kotlin-sample-kotlin: kotlin-module, kotlin-operation info kotlin-sample-package: package

create Generating Multi module (Your project parent POM) info Parameters: Use a parent artifact, Parent group, Parent artifact, Parent version, Import nuxeo in the `dependency management`, Nuxeo version, Project group, Project artifact, Project version, Project description ? Use a parent artifact (for instance your company's BOM or the org.nuxeo.ecm.distribution:nuxeo-distribution POM)? Yes ? Parent Group id: org.nuxeo.ecm.distribution ? Parent Artifact id: nuxeo-distribution ? Parent Version: 9.1 ? Project Group id: org.nuxeo.sample ? Project Artifact id: kotlin-sample-parent ? Project Version: 1.0-SNAPSHOT ? Project Description:

create Generate Module: kotlin-sample-kotlin

create Generating Kotlin module info Parameters: Nuxeo version, Project group, Project artifact, Project version, Project description ? Project Group id: org.nuxeo.sample ? Project Artifact id: kotlin-sample-kotlin ? Project version: 1.0-SNAPSHOT ? Project description:

create Generating Kotlin operation info Parameters: Operation class name, Operation label ? Operation class name: SampleOperation ? Operation label: My Kotlin Operation

create Generate Module: kotlin-sample-package

create Generating Package info Parameters: Package artifact, Package version, Package name, Company name ? Package Artifact id: kotlin-sample-package ? Package Version: 1.0-SNAPSHOT ? Package name: kotlin-sample ? Company name:

最初の Kotlin オペレーション

次のような Kotlin ベースのオペレーションが生成されます。このオペレーションの動作は Java 版とほぼ同じです。

`kotlin package org.nuxeo.sample

import org.nuxeo.ecm.automation.core.Constants import org.nuxeo.ecm.automation.core.annotations.Context import org.nuxeo.ecm.automation.core.annotations.Operation import org.nuxeo.ecm.automation.core.annotations.OperationMethod import org.nuxeo.ecm.automation.core.annotations.Param import org.nuxeo.ecm.core.api.CoreSession import org.nuxeo.ecm.core.api.DocumentModel import org.nuxeo.ecm.core.api.PathRef

@Operation(id = “Document.SampleOperation”, category = Constants.CAT_DOCUMENT, label=”My Kotlin Operation”, description=”Describe here what your operation does.”) open class SampleOperation {

@Context protected lateinit var session: CoreSession

@Param(name = “path”, required = false) protected var path: String? = null

@OperationMethod fun run(): DocumentModel { return when { path.isNullOrBlank() -> session.rootDocument else -> session.getDocument(PathRef(path)) } } }


当然のことながら、他のどの Nuxeo バンドルもそうであるように、このオペレーションはマニフェストに寄稿され、言及されています。

### Maven ビルドプラグイン

[Kotlin Maven ビルドプラグイン](https://kotlinlang.org/docs/reference/using-maven.html)が追加され、次のように正しくコンパイルするようになっています。

```xml
<plugin>
  <artifactid>kotlin-maven-plugin</artifactid>
  <groupid>org.jetbrains.kotlin</groupid>
  <version>${kotlin.version}</version>
  <executions>
    <execution>
      <id>compile</id>
      <goals>
        <goal>compile</goal>
      </goals>
    </execution>
    <execution>
      <id>test-compile</id>
      <goals>
        <goal>test-compile</goal>
      </goals>
    </execution>
  </executions>
</plugin>

展開

他のどの Nuxeo バンドルもそうであるように、mvn packageを実行してプロジェクトをビルドし、「$NUXEO_HOME/nxserver/bundles」フォルダにバンドルを配置することができます。

ただし、Nuxeo サーバを起動する前に、関連する JetBrains Kotlin ランタイムライブラリNUXEO_HOME/nxserver/libで忘れずに設定しておく必要があります。

うれしいことに、ランタイムライブラリの設定は、先ほど作成したNuxeo パッケージを使用して自動的に処理されます。パッケージを展開する以外に必要な操作は何もありません。

# Build the whole bundle cd $PROJECT_ROOT && mvn package

# Ensure your server is stopped $NUXEO_HOME/bin/nuxeoctl stop

# Install your bundle $NUXEO_HOME/bin/nuxeoctl mp-install $PROJECT_ROOT/kotlin-sample-package/target/kotlin-sample-package-*.zip

# Start your server $NUXEO_HOME/bin/nuxeoctl start

次に、オペレーションの定義を取得し、curlを使用して呼び出してみましょう。

# Get Operation Documentation curl -u Administrator:Administrator http://localhost:8080/nuxeo/site/automation/Document.SampleOperation

# Execute the Operation curl -H 'Content-Type:application/json+nxrequest' -X POST -d '{"params":{},"context":{}}' -u Administrator:Administrator http://localhost:8080/nuxeo/api/v1/automation/Document.SampleOperation

このように素晴らしい結果が得られます!

デバッグ

オペレーションの任意の場所に「ブレークポイント」を追加し、IDE リモートデバッグ機能を使用して Nuxeo(ポート 8787)に接続します。Kotlin と Java の両方で全ステップを実行できるようになります!

Debug

テスト

Kotlin を使用するとコーディングにかかる時間を短縮できますが、コードをテストする必要がなくなるわけではありません!

TestSampleOperationファイルに示されているとおり、テストフレームワークを使用してコードをテストできます。

@RunWith(FeaturesRunner::class) @Features(AutomationFeature::class) @Deploy("org.nuxeo.sample.kotlin-sample-kotlin") open class TestSampleOperation {

@Inject protected lateinit var session: CoreSession

... }

この洗練された最新のプログラミング言語を実際に使用して、その魅力を確かめてください!