Java のデプロイ オプション

Java 関数をデプロイするには、次の 2 つの方法があります。

ソースからのデプロイ

関数のソースコードは、Maven プロジェクト(src/main/java)の通常の場所に配置する必要があります。このドキュメントのサンプル関数は src/main/java 内に直接あり、.java ソースファイルにパッケージ宣言はありません。簡単なコードの場合は、パッケージを導入します。パッケージが com.example の場合、階層は次のようになります。

myfunction/
├─ pom.xml
├─ src
    ├─main
        ├─ java
            ├─ com
                ├─ example
                    ├─ MyFunction.java

HTTP 関数をデプロイするには、次のコマンドを使用します。

gcloud functions deploy $name \
    --trigger-http \
    --gen2 \
    --region=REGION \
    --entry-point $function_class \
    --runtime java17 

ここで

  • $name は、デプロイ後の関数の名前になる任意のわかりやすい名前です。$name には文字、数字、アンダースコア、ハイフンのみを使用できます。
  • $function_class はクラスの完全修飾名です(パッケージを使用しない場合は、com.example.MyFunction または MyFunction のみを使用します)。

イベント ドリブン関数をデプロイするには、次のコマンドを使用します。

gcloud functions deploy $name \
    --entry-point $function_class \
    --gen2 \
    --region=REGION \
    --trigger-resource $resource_name \
    --trigger-event $event_name \
    --runtime java17

ここで

  • $name は、デプロイ後の関数の名前になる任意のわかりやすい名前です。
  • $function_class はクラスの完全修飾名です(パッケージを使用しない場合は、com.example.MyFunction または MyFunction のみを使用します)。
  • $resource_name$event_name は、イベント ドリブン関数をトリガーするイベントに固有のものです。サポートされるリソースやイベントの例として、Google Cloud Pub/SubGoogle Cloud Storage などがあります。

ソースから関数をデプロイする場合、Google Cloud CLI はソース ディレクトリ(とその中のすべてのもの)を Google Cloud にアップロードしてビルドします。不要なファイルの送信を防ぐには、.gcloudignore ファイルを使用します。.gittarget/ などの一般的なディレクトリを無視するように .gcloudignore ファイルを編集します。たとえば、.gcloudignore ファイルには次のものが含まれます。

.git
target
build
.idea

JAR からのデプロイ

関数を含むビルド済みの JAR をデプロイできます。これは、ソースからのビルド時に Google Cloud のビルド パイプラインからアクセスできないプライベート アーティファクト リポジトリの依存関係を使用する関数をデプロイする場合に役立ちます。JAR は、関数クラスとそのすべての依存関係クラスを含む Uber JAR や、META-INF/MANIFEST.MF ファイル内の依存関係 JAR 用の Class-Path エントリを持つ thin JAR のいずれかです。

Uber JAR をビルドしてデプロイ

Uber JAR は、関数クラスとすべての依存関係を含む JAR ファイルです。Maven と Gradle の両方で Uber JAR をビルドできます。Uber JAR をデプロイするには、その Uber JAR がディレクトリ内で使用されている唯一の JAR ファイルである必要があります。次に例を示します。

my-function-deployment/
 ├─ my-function-with-all-dependencies.jar

このディレクトリ構造にファイルをコピーするか、Maven プラグインと Gradle プラグインを使用して正しいデプロイ ディレクトリを生成します。

Maven

Maven Shade プラグインを使用して Uber JAR をビルドします。Shade プラグインを使用して pom.xml を構成します。

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  ...
  <build>
    ...
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals><goal>shade</goal></goals>
            <configuration>
              <outputFile>${project.build.directory}/deployment/${build.finalName}.jar</outputFile>
              <transformers>
                <!-- This may be needed if you need to shade a signed JAR -->
                <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
                  <resource>.SF</resource>
                  <resource>.DSA</resource>
                  <resource>.RSA</resource>
                </transformer>
                <!-- This is needed if you have dependencies that use Service Loader. Most Google Cloud client libraries does. -->
                <transformer implementation=
       "org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Uber JAR をビルドします。

mvn package

次のコマンドを使用してデプロイします。

gcloud functions deploy jar-example \
    --gen2 \
    --entry-point=Example \
    --runtime=java17 \
    --region=REGION \
    --trigger-http \
    --source=target/deployment

Gradle

Gradle 用の Shadow プラグインを使用します。build.gradle ファイルでプラグインを設定します。

buildscript {
   repositories {
       jcenter()
   }
   dependencies {
       ...
       classpath "com.github.jengelman.gradle.plugins:shadow:5.2.0"
   }
}

plugins {
   id 'java'
   ...
}
sourceCompatibility = '17.0'
targetCompatibility = '17.0'
apply plugin: 'com.github.johnrengelman.shadow'

shadowJar {
   mergeServiceFiles()
}
...

これで、shadowJar コマンドを使用して Gradle を実行できるようになりました。

gradle shadowJar

次のコマンドを使用してデプロイします。

gcloud functions deploy jar-example \
   --entry-point=Example \
   --runtime=java17 \
   --trigger-http \
   --source=build/libs

外部依存関係を持つ thin JAR をビルドしてデプロイする

Uber JAR の代わりに thin JAR ファイルをビルドしてデプロイできます。thin JAR は、同じ JAR ファイルに依存関係が埋め込まれていない関数クラスのみを含む JAR ファイルです。デプロイには依存関係が必要であるため、次のように設定する必要があります。

  • 依存関係は、デプロイする JAR に関連するサブディレクトリに配置する必要があります。
  • JAR には、必要な依存関係パスをリストする値を持つ Class-Path 属性を含む META-INF/MANIFEST.MF ファイルが必要です。

たとえば、JAR ファイルの my-function.jar には、libs/ ディレクトリに 2 つの依存関係(相対パスのスペース区切りリスト)が含まれている META-INF/MANIFEST.MF ファイルがあります。

Manifest-Version: 1.0
Class-Path: libs/dep1.jar libs/dep2.jar

デプロイ ディレクトリには、メインの関数 JAR ファイルと、関数が依存する 2 つの依存関係を持つサブディレクトリが含まれている必要があります。

function-deployment/
├─ my-function.jar
├─ libs
       ├─ dep1.jar
       ├─ dep2.jar

Maven と Gradle の両方で thin JAR をビルドできます。

Maven

Maven JAR プラグインを使用して、依存関係へのパスによって自動的に MANIFEST.MF を構成し、Maven 依存関係プラグインを使用して依存関係をコピーします。

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  ...
  <build>
    ...
    <plugins>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <classpathPrefix>libs/</classpathPrefix>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <overWriteReleases>false</overWriteReleases>
              <includeScope>runtime</includeScope>
              <outputDirectory>${project.build.directory}/libs</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <executions>
          <execution>
            <id>copy-resources</id>
            <phase>package</phase>
            <goals><goal>copy-resources</goal></goals>
            <configuration>
              <outputDirectory>${project.build.directory}/deployment</outputDirectory>
              <resources>
                <resource>
                  <directory>${project.build.directory}</directory>
                  <includes>
                    <include>${build.finalName}.jar</include>
                    <include>libs/**</include>
                  </includes>
                  <filtering>false</filtering>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

thin JAR をビルドします。

mvn package

次のコマンドを使用してデプロイします。

gcloud functions deploy jar-example \
--gen2 \
--region=REGION \
--entry-point=Example \
--runtime=java17 \
--trigger-http \
--source=target/deployment

Gradle

build.gradle プロジェクト ファイルを更新して、依存関係を取得する新しいタスクを追加します。

dependencies {
   // API available at compilation only, but provided at runtime
   compileOnly 'com.google.cloud.functions:functions-framework-api:1.0.1'
   // dependencies needed by the function
   // ...
}

jar {
 manifest {
   attributes(
     "Class-Path": provider {
         configurations.runtimeClasspath
           .collect { "libs/${it.name}" }.join(' ')
     }
   )
 }
}

task prepareDeployment(type: Copy) {
 into("${buildDir}/deployment")
 into('.') {
   from jar
 }
 into('libs') {
   from configurations.runtimeClasspath
 }
}