Java Deployment Options
You have two choices for deploying a Java function:
- From source . For a general discussion of this topic, see Deploy a Cloud Function .
- From a pre-packaged JAR file .
Deploy from source
Your function's source code must be in the usual place for Maven projects
( src/main/java
). The sample functions in this document are directly in src/main/java
, with no package declaration in the .java
source file. For
non-trivial code, you would likely introduce a package. If that package is com.example
, then your hierarchy would look like this:
myfunction/ ├─ pom.xml ├─ src ├─main ├─ java ├─ com ├─ example ├─ MyFunction.java
Use the following command to deploy an HTTP function:
gcloud
functions
deploy
$name
--
trigger
-
http
--
no
-
gen2
\
--
entry
-
point
$function_class
--
runtime
java17
Where:
-
$name
is an arbitrary, descriptive name that will be the name of the function once deployed.$name
can only contain letters, numbers, underscores, and hyphens. -
$function_class
is the fully qualified name of your class (for example,com.example.MyFunction
or justMyFunction
if you don't use a package).
Use the following command to deploy an event-driven function:
gcloud
functions
deploy
$name
--
no
-
gen2
--
entry
-
point
$function_class
\
--
trigger
-
resource
$resource_name
\
--
trigger
-
event
$event_name
\
--
runtime
java17
Where:
-
$name
is an arbitrary, descriptive name that will be the name of the function once deployed. -
$function_class
is the fully qualified name of your class (for example,com.example.MyFunction
or justMyFunction
if you don't use a package). -
$resource_name
and$event_name
are specific to the events that trigger your function. Examples of supported resources and events are Google Cloud Pub/Sub and Google Cloud Storage .
When deploying a function from source, the Google Cloud CLI uploads
the source directory (and everything in it) to Google Cloud to build. To avoid
sending unnecessary files, you can use the .gcloudignore
file
. Edit the .gcloudignore
file
to ignore common directories like .git
and target/
. For example, a .gcloudignore
file might contain the following:
.
git
target
build
.
idea
Deploy from a JAR
You can deploy a pre-built JAR that contains the function. This is useful
especially if you need to deploy a function that uses dependencies from a
private artifact repository that cannot be accessed from Google Cloud's
build pipeline when building from source. The JAR can be an uber JAR that
contains the function class and all of its dependency classes, or a thin JAR
that has Class-Path
entries for dependency JARs in the META-INF/MANIFEST.MF
file.
Build and deploy an Uber JAR
An uber JAR is a JAR file that contains the function classes as well as all of its dependencies. You can build an uber JAR with both Maven and Gradle. To deploy a Uber JAR, it must be the only JAR file in its own directory, for example:
my-function-deployment/ ├─ my-function-with-all-dependencies.jar
You can either copy the file into this directory structure, or use Maven and Gradle plugins to generate the correct deployment directory.
Maven
Use the Maven Shade plugin
to build an uber JAR. Configure your pom.xml
with Shade plugin:
< ?
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
>
Build the uber JAR:
mvn package
Then deploy with the following command:
gcloud
functions
deploy
jar
-
example
\
--
entry
-
point
=
Example
\
--
no
-
gen2
\
--
runtime
=
java17
\
--
trigger
-
http
\
--
source
=
target
/
deployment
Gradle
Use the Shadow plugin
for Gradle. Setup the plugin in your build.gradle
file:
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() } ...
Now you can run Gradle with the shadowJar
command:
gradle
shadowJar
Then deploy with the following command:
gcloud
functions
deploy
jar
-
example
\
--
entry
-
point
=
Example
\
--
no
-
gen2
\
--
runtime
=
java17
\
--
trigger
-
http
\
--
source
=
build
/
libs
Build and deploy a thin JAR with external dependencies
You can build and deploy a thin JAR file rather than an uber JAR. A thin JAR is a JAR file that contains only the function classes without the dependencies embedded in the same JAR file. Because the dependencies are still needed for deployment, you need to set things up as follows:
- The dependencies must be in a subdirectory relative to the JAR to be deployed.
- The JAR must have a
META-INF/MANIFEST.MF
file that includes aClass-Path
attribute whose value lists the required dependency paths.
For example, your JAR file my-function.jar has a META-INF/MANIFEST.MF
file
that has 2 dependencies in the libs/
directory (a space-separated list of
relative paths):
Manifest
-
Version
:
1.0
Class
-
Path
:
libs
/
dep1
.
jar
libs
/
dep2
.
jar
Your deployment directory should then contain your main function JAR file, as well as a subdirectory with the two dependencies your function depends on:
function-deployment/ ├─ my-function.jar ├─ libs ├─ dep1.jar ├─ dep2.jar
You can build a thin JAR with both Maven and Gradle:
Maven
Use Maven JAR plugin to automatically configure MANIFEST.MF
with the paths
to the dependencies, and then use the Maven Dependency plugin
to copy the dependencies.
< ?
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
>
Build the thin JAR:
mvn package
Then deploy with the following command:
gcloud
functions
deploy
jar
-
example
\
--
entry
-
point
=
Example
\
--
no
-
gen2
\
--
runtime
=
java17
\
--
trigger
-
http
\
--
source
=
target
/
deployment
Gradle
Update your build.gradle
project file to add a new task to fetch the
dependencies:
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 } }