Opsi Deployment Java

Anda memiliki dua pilihan untuk men-deploy fungsi Java:

Men-deploy dari sumber

Kode sumber fungsi Anda harus berada di tempat biasa untuk project Maven (src/main/java). Contoh fungsi dalam dokumen ini berada langsung di src/main/java, tanpa deklarasi paket di file sumber .java. Untuk kode yang tidak sepele, Anda mungkin akan memperkenalkan paket. Jika paket tersebut adalah com.example, hierarki Anda akan terlihat seperti ini:

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

Gunakan perintah berikut untuk men-deploy fungsi HTTP:

gcloud functions deploy $name --trigger-http \
    --entry-point $function_class --runtime java17

Dengan keterangan:

  • $name adalah nama deskriptif arbitrer yang akan menjadi nama fungsi setelah di-deploy. $name hanya boleh berisi huruf, angka, garis bawah, dan tanda hubung.
  • $function_class adalah nama class Anda yang sepenuhnya memenuhi syarat (misalnya, com.example.MyFunction, atau cukup MyFunction jika Anda tidak menggunakan paket).

Gunakan perintah berikut untuk men-deploy fungsi berbasis peristiwa:

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

Dengan keterangan:

  • $name adalah nama deskriptif arbitrer yang akan menjadi nama fungsi setelah di-deploy.
  • $function_class adalah nama class Anda yang sepenuhnya memenuhi syarat (misalnya, com.example.MyFunction, atau cukup MyFunction jika Anda tidak menggunakan paket).
  • $resource_name dan $event_name dikhususkan untuk peristiwa yang memicu fungsi Anda. Contoh resource dan peristiwa yang didukung adalah Google Cloud Pub/Sub dan Google Cloud Storage.

Saat men-deploy fungsi dari sumber, Google Cloud CLI mengupload direktori sumber (dan semua yang ada di dalamnya) ke Google Cloud untuk dibangun. Untuk menghindari pengiriman file yang tidak perlu, Anda dapat menggunakan file .gcloudignore. Edit file .gcloudignore untuk mengabaikan direktori umum seperti .git dan target/. Misalnya, file .gcloudignore mungkin berisi hal berikut:

.git
target
build
.idea

Men-deploy dari JAR

Anda dapat men-deploy JAR bawaan yang berisi fungsi tersebut. Hal ini berguna terutama jika Anda perlu men-deploy fungsi yang menggunakan dependensi dari repositori artefak pribadi yang tidak dapat diakses dari pipeline build Google Cloud saat membangun dari sumber. JAR dapat berupa JAR uber yang berisi class fungsi dan semua class dependensinya, atau JAR tipis yang memiliki entri Class-Path untuk JAR dependensi dalam file META-INF/MANIFEST.MF.

Membangun dan men-deploy JAR Uber

JAR uber adalah file JAR yang berisi class fungsi serta semua dependensinya. Anda bisa membuat JAR uber dengan Maven dan Gradle. Untuk men-deploy Uber JAR, file tersebut harus menjadi satu-satunya file JAR di direktorinya sendiri, misalnya:

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

Anda dapat menyalin file ke struktur direktori ini, atau menggunakan plugin Maven dan Gradle untuk membuat direktori deployment yang benar.

Maven

Gunakan plugin Maven Shade untuk membuat JAR uber. Konfigurasikan pom.xml Anda dengan plugin Shade:

<?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>

Bangun JAR uber:

mvn package

Kemudian deploy dengan perintah berikut:

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

Gradle

Gunakan plugin Shadow untuk Gradle. Siapkan plugin di file build.gradle Anda:

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()
}
...

Sekarang Anda dapat menjalankan Gradle dengan perintah shadowJar:

gradle shadowJar

Kemudian deploy dengan perintah berikut:

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

Membangun dan men-deploy JAR tipis dengan dependensi eksternal

Anda bisa membangun dan men-deploy file JAR tipis daripada JAR uber. JAR tipis adalah file JAR yang hanya berisi class fungsi tanpa dependensi yang disematkan dalam file JAR yang sama. Karena dependensi masih diperlukan untuk deployment, Anda perlu menyiapkan beberapa hal berikut:

  • Dependensi harus berada dalam subdirektori yang relatif terhadap JAR agar dapat di-deploy.
  • JAR harus memiliki file META-INF/MANIFEST.MF yang menyertakan atribut Class-Path yang nilainya mencantumkan jalur dependensi yang diperlukan.

Misalnya, file JAR my-function.jar memiliki file META-INF/MANIFEST.MF yang memiliki 2 dependensi di direktori libs/ (daftar jalur relatif yang dipisahkan spasi):

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

Direktori deployment Anda selanjutnya harus berisi file JAR fungsi utama, serta subdirektori dengan dua dependensi yang menjadi dependensi fungsi Anda:

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

Anda bisa membuat JAR tipis dengan Maven dan Gradle:

Maven

Gunakan plugin Maven JAR untuk mengonfigurasi MANIFEST.MF secara otomatis dengan jalur ke dependensi, lalu gunakan plugin Maven Dependency untuk menyalin dependensi.

<?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>

Bangun JAR tipis:

mvn package

Kemudian deploy dengan perintah berikut:

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

Gradle

Perbarui file project build.gradle Anda untuk menambahkan tugas baru untuk mengambil dependensi:

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
 }
}