Opções de implantação Java
Há duas opções para implantar uma função do Java:
- A partir da origem. Para uma discussão geral sobre esse tópico, consulte Implantar uma função do Cloud.
- De um arquivo JAR pré-empacotado.
Implantar a partir da origem
O código-fonte da função precisa estar no lugar usual de projetos
Maven (src/main/java
). As funções de amostra neste documento estão diretamente em
src/main/java
, sem declaração de pacote no arquivo de origem .java
. Para
códigos não triviais, você provavelmente introduziria um pacote. Se esse pacote for
com.example
, a hierarquia será assim:
myfunction/ ├─ pom.xml ├─ src ├─main ├─ java ├─ com ├─ example ├─ MyFunction.java
Use o seguinte comando para implantar uma função HTTP:
gcloud functions deploy $name --trigger-http \
--entry-point $function_class --runtime java17
Em que:
$name
é um nome descritivo arbitrário e que será o nome da função depois de implantado.$name
deve conter apenas letras, números, sublinhados e hifens.$function_class
é o nome totalmente qualificado da sua classe (por exemplo,com.example.MyFunction
ou apenasMyFunction
se você não usar um pacote).
Use o seguinte comando para implantar uma função orientada a eventos:
gcloud functions deploy $name --no-gen2 --entry-point $function_class \
--trigger-resource $resource_name \
--trigger-event $event_name \
--runtime java17
Em que:
$name
é um nome descritivo arbitrário e que será o nome da função depois de implantado.$function_class
é o nome totalmente qualificado da sua classe (por exemplo,com.example.MyFunction
ou apenasMyFunction
se você não usar um pacote).$resource_name
e$event_name
são específicos para os eventos que acionam a função em segundo plano. Exemplos de recursos e eventos compatíveis são o Google Cloud Pub/Sub e o Google Cloud Storage.
Ao implantar uma função a partir da origem, a CLI do Google Cloud faz upload
do diretório de origem (e de tudo que há nele) para o Google Cloud. Para evitar o envio de arquivos desnecessários, use o
arquivo .gcloudignore
. Edite o arquivo .gcloudignore
para ignorar diretórios comuns, como .git
e target/
. Por exemplo, um arquivo
.gcloudignore
pode conter o seguinte:
.git
target
build
.idea
Implantar a partir de um JAR
É possível implantar um JAR pré-criado que contém a função. Isso é útil
principalmente se você precisar implantar uma função que use dependências de um
repositório de artefatos particular que não possa ser acessado a partir do pipeline de compilação do Google Cloud
ao compilar a partir da origem. O JAR pode ser um JAR uber que
contenha a classe de função e todas as suas classes de dependência ou um JAR thin
que tem entradas Class-Path
para JARs de dependência no arquivo META-INF/MANIFEST.MF
.
Criar e implantar um Uber JAR
Um JAR uber é um arquivo JAR que contém as classes de função e todas as suas dependências. É possível criar um JAR uber com o Maven e o Gradle. Para implantar um JAR uber, ele precisa ser o único arquivo JAR no próprio diretório. Por exemplo:
my-function-deployment/ ├─ my-function-with-all-dependencies.jar
Copie o arquivo nessa estrutura de diretórios ou use os plug-ins Maven e Gradle para gerar o diretório de implantação correto.
Maven
Use o plug-in Maven Shade para criar um JAR uber. Configure seu pom.xml
com o plug-in 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>
Crie o JAR uber:
mvn package
Em seguida, implante com o seguinte comando:
gcloud functions deploy jar-example \
--entry-point=Example \
--runtime=java17 \
--trigger-http \
--source=target/deployment
Gradle
Use o plug-in Shadow
para Gradle. Configure o plug-in no seu arquivo 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() } ...
Agora é possível executar o Gradle com o comando shadowJar
:
gradle shadowJar
Em seguida, implante com o seguinte comando:
gcloud functions deploy jar-example \
--entry-point=Example \
--runtime=java17 \
--trigger-http \
--source=build/libs
Criar e implantar um thin JAR com dependências externas
É possível criar e implantar um arquivo JAR thin em vez de um JAR uber. Um JAR thin é um arquivo JAR que contém apenas as classes de função sem as dependências incorporadas no mesmo arquivo JAR. Como as dependências ainda são necessárias para implantação, é necessário fazer as configurações da seguinte maneira:
- As dependências precisam estar em um subdiretório relativo ao JAR a ser implantado.
- O JAR precisa ter um arquivo
META-INF/MANIFEST.MF
que inclua um atributoClass-Path
, que tenha um valor que liste os caminhos de dependência necessários.
Por exemplo, seu arquivo JAR my-function.jar tem um arquivo META-INF/MANIFEST.MF
que tem duas dependências no diretório libs/
(uma lista separada por espaço de
caminhos relativos):
Manifest-Version: 1.0
Class-Path: libs/dep1.jar libs/dep2.jar
Seu diretório de implantação conterá seu arquivo JAR de função principal e um subdiretório com as duas dependências de que sua função depende:
function-deployment/ ├─ my-function.jar ├─ libs ├─ dep1.jar ├─ dep2.jar
É possível criar um JAR simples com o Maven e o Gradle:
Maven
Use o plug-in Maven JAR para configurar automaticamente MANIFEST.MF
com os caminhos para
as dependências e, em seguida, use o
plug-in de dependência do Maven
para copiar as dependências.
<?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>
Crie o JAR thin:
mvn package
Em seguida, implante com o seguinte comando:
gcloud functions deploy jar-example \
--entry-point=Example \
--runtime=java17 \
--trigger-http \
--source=target/deployment
Gradle
Atualize o arquivo do projeto build.gradle
para adicionar uma nova tarefa para buscar as
dependências:
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 } }