diff --git a/tasks/native-image-sample/README.md b/tasks/native-image-sample/README.md
new file mode 100644
index 00000000000..acbbe7ff5bb
--- /dev/null
+++ b/tasks/native-image-sample/README.md
@@ -0,0 +1,119 @@
+# Cloud Tasks Sample Application with Native Image
+
+The Cloud Tasks sample application demonstrates some common operations with
+[Google Cloud Tasks](https://cloud.google.com/tasks) and is compatible with
+Native Image compilation.
+
+This application will create a new queue called `graal-test-queue` if it does
+not already exist.
+It will then submit a new task to this queue.
+
+## Setup Instructions
+
+1. Follow the [GCP Project and Native Image Setup Instructions](../../README.md).
+
+2. [Enable the Cloud Tasks APIs](https://console.cloud.google.com/apis/api/cloudtasks.googleapis.com).
+
+### Run with Native Image Compilation
+
+Navigate to this directory in a new terminal.
+
+1. Compile the application using the Native Image Compiler. This step may take a few minutes.
+
+ ```
+ $ mvn package -P native
+ ```
+
+ The project uses an environment variable `LOCATION_ID` to run the test.
+
+2. Run the application:
+
+ ```
+ $ LOCATION_ID=us-east1 ./target/tasks-sample
+ ```
+
+ The sample application uses an environment variable `LOCATION_ID`.
+
+3. The application runs through some basic Cloud Tasks operations (create queue, create task) and then prints some results of the operations.
+
+ ```
+ Test queue ready: name: "projects/xxxxxxxxxx/locations/us-central1/queues/graal-test-queue-4009"
+ rate_limits {
+ max_dispatches_per_second: 500.0
+ max_burst_size: 100
+ max_concurrent_dispatches: 1
+ }
+ retry_config {
+ max_attempts: 100
+ min_backoff {
+ nanos: 100000000
+ }
+ max_backoff {
+ seconds: 3600
+ }
+ max_doublings: 16
+ }
+ state: RUNNING
+
+ Created task: name: "projects/xxxxxxxxxx/locations/us-central1/queues/graal-test-queue-4009/tasks/5886258204485021611"
+ http_request {
+ url: "https://google.com/"
+ http_method: GET
+ headers {
+ key: "User-Agent"
+ value: "Google-Cloud-Tasks"
+ }
+ }
+ schedule_time {
+ seconds: 1613189391
+ nanos: 486293000
+ }
+ create_time {
+ seconds: 1613189391
+ }
+ dispatch_deadline {
+ seconds: 600
+ }
+ view: BASIC
+
+ Queue purged
+ Queue deleted
+ ```
+
+4. Run the test in the project in the native-image mode
+
+ ```
+ $ LOCATION_ID=us-east1 mvn test -P native
+ ...
+ [INFO] -------------------------------------------------------
+ [INFO] T E S T S
+ [INFO] -------------------------------------------------------
+ [INFO] Running com.example.tasks.ITNativeImageTasksSample
+ ...
+ [INFO] --- native-maven-plugin:0.9.9:test (test-native) @ native-image-sample ---
+ [INFO] ====================
+ [INFO] Initializing project: native-image-sample
+ ...
+ com.example.tasks.ITNativeImageTasksSample > testRunSampleApplication SUCCESSFUL
+
+
+ Test run finished after 1025 ms
+ [ 3 containers found ]
+ [ 0 containers skipped ]
+ [ 3 containers started ]
+ [ 0 containers aborted ]
+ [ 3 containers successful ]
+ [ 0 containers failed ]
+ [ 1 tests found ]
+ [ 0 tests skipped ]
+ [ 1 tests started ]
+ [ 0 tests aborted ]
+ [ 1 tests successful ]
+ [ 0 tests failed ]
+
+ [INFO] ------------------------------------------------------------------------
+ [INFO] BUILD SUCCESS
+ [INFO] ------------------------------------------------------------------------
+ [INFO] Total time: 02:27 min
+ ...
+ ```
diff --git a/tasks/native-image-sample/pom.xml b/tasks/native-image-sample/pom.xml
new file mode 100644
index 00000000000..42d75d30ed7
--- /dev/null
+++ b/tasks/native-image-sample/pom.xml
@@ -0,0 +1,150 @@
+
+
+ 4.0.0
+ com.example.tasks
+ native-image-sample
+ Native Image Sample
+
+
+
+ com.google.cloud.samples
+ shared-configuration
+ 1.2.0
+
+
+
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+
+
+ com.google.cloud
+ libraries-bom
+ 24.2.0
+ pom
+ import
+
+
+
+
+
+
+ com.google.cloud
+ google-cloud-core
+
+
+ com.google.cloud
+ google-cloud-tasks
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+ com.google.truth
+ truth
+ 1.1.3
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ com.example.TasksSampleApplication
+
+
+
+
+
+
+
+
+
+ native
+
+
+
+ com.google.cloud
+ native-image-support
+ 0.10.0
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ 5.8.2
+
+
+ org.graalvm.buildtools
+ junit-platform-native
+ 0.9.9
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ 2.22.2
+
+
+ **/IT*
+
+
+
+
+ org.graalvm.buildtools
+ native-maven-plugin
+ 0.9.9
+ true
+
+ com.example.tasks.TasksSampleApplication
+
+ --no-fallback
+ --no-server
+ --initialize-at-build-time
+ --features=com.google.cloud.nativeimage.features.ProtobufMessageFeature
+
+
+
+
+ build-native
+
+ build
+ test
+
+ package
+
+
+ test-native
+
+ test
+
+ test
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tasks/native-image-sample/src/main/java/com/example/tasks/TasksSampleApplication.java b/tasks/native-image-sample/src/main/java/com/example/tasks/TasksSampleApplication.java
new file mode 100644
index 00000000000..de736aa88a1
--- /dev/null
+++ b/tasks/native-image-sample/src/main/java/com/example/tasks/TasksSampleApplication.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.tasks;
+
+import com.google.cloud.ServiceOptions;
+import com.google.cloud.tasks.v2.CloudTasksClient;
+import com.google.cloud.tasks.v2.CreateQueueRequest;
+import com.google.cloud.tasks.v2.HttpMethod;
+import com.google.cloud.tasks.v2.HttpRequest;
+import com.google.cloud.tasks.v2.LocationName;
+import com.google.cloud.tasks.v2.Queue;
+import com.google.cloud.tasks.v2.QueueName;
+import com.google.cloud.tasks.v2.RateLimits;
+import com.google.cloud.tasks.v2.Task;
+import java.io.IOException;
+import java.util.UUID;
+
+/** Sample application demonstrating Native Image compatibility with Google Cloud Tasks APIs. */
+public class TasksSampleApplication {
+ /**
+ * Queue name randomness added to avoid FAILED_PRECONDITION: The queue cannot be created because a
+ * queue with this name existed too recently.
+ */
+ private static final String GRAALVM_TEST_QUEUE_NAME = "graal-test-queue-";
+
+ private static final String LOCATION_ID = System.getenv("LOCATION_ID");
+
+ /** Runs the Cloud Tasks sample application. */
+ public static void main(String[] args) throws IOException {
+ String projectId = ServiceOptions.getDefaultProjectId();
+ LocationName parent = LocationName.of(projectId, LOCATION_ID);
+ QueueName queueName =
+ QueueName.of(
+ parent.getProject(),
+ parent.getLocation(),
+ GRAALVM_TEST_QUEUE_NAME + UUID.randomUUID().toString());
+
+ try (CloudTasksClient client = CloudTasksClient.create()) {
+ // Create queue
+ Queue queue =
+ Queue.newBuilder()
+ .setName(queueName.toString())
+ .setRateLimits(RateLimits.newBuilder().setMaxConcurrentDispatches(1).build())
+ .build();
+
+ CreateQueueRequest createQueueRequest =
+ CreateQueueRequest.newBuilder().setParent(parent.toString()).setQueue(queue).build();
+
+ Queue createdQueue = client.createQueue(createQueueRequest);
+ System.out.println("Test queue ready: " + createdQueue);
+
+ // Create task
+ HttpRequest taskTarget =
+ HttpRequest.newBuilder()
+ .setUrl("https://google.com")
+ .setHttpMethod(HttpMethod.GET)
+ .build();
+
+ Task taskRequest = Task.newBuilder().setHttpRequest(taskTarget).build();
+ Task task = client.createTask(queueName, taskRequest);
+ System.out.println("Created task: " + task);
+
+ // Cleanup
+ client.purgeQueue(queueName);
+ System.out.println("Queue purged");
+
+ client.deleteQueue(queueName);
+ System.out.println("Queue deleted");
+ }
+ }
+}
diff --git a/tasks/native-image-sample/src/test/java/com/example/tasks/ITNativeImageTasksSample.java b/tasks/native-image-sample/src/test/java/com/example/tasks/ITNativeImageTasksSample.java
new file mode 100644
index 00000000000..70e91ffa1b9
--- /dev/null
+++ b/tasks/native-image-sample/src/test/java/com/example/tasks/ITNativeImageTasksSample.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.tasks;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ITNativeImageTasksSample {
+ private ByteArrayOutputStream bout;
+
+ @Before
+ public void setUp() throws Exception {
+ bout = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(bout));
+ }
+
+ @Test
+ public void testRunSampleApplication() throws Exception {
+ TasksSampleApplication.main(new String[] {});
+ String output = bout.toString();
+ assertThat(output).contains("Test queue ready");
+ assertThat(output).contains("Queue purged");
+ assertThat(output).contains("Queue deleted");
+ }
+}
diff --git a/tasks/pom.xml b/tasks/pom.xml
index 92ea1f877e1..87ddc149db9 100644
--- a/tasks/pom.xml
+++ b/tasks/pom.xml
@@ -31,6 +31,7 @@
install-without-bom
snapshot
snippets
+ native-image-sample