From 29e4ee939e779ad33547c2dd92485c1432538131 Mon Sep 17 00:00:00 2001 From: Alan Ramirez Herrera Date: Mon, 1 Sep 2025 21:05:59 +0000 Subject: [PATCH 1/6] chore(bigtable): update bigtable example from java8 to java21 --- appengine-java21/ee8/bigtable/README.md | 59 ++++++ appengine-java21/ee8/bigtable/build.gradle | 113 +++++++++++ .../gradle/wrapper/gradle-wrapper.properties | 6 + appengine-java21/ee8/bigtable/gradlew | 172 ++++++++++++++++ appengine-java21/ee8/bigtable/gradlew.bat | 84 ++++++++ appengine-java21/ee8/bigtable/pom.xml | 184 ++++++++++++++++++ appengine-java21/ee8/bigtable/settings.gradle | 1 + .../example/bigtable/BigtableHelloWorld.java | 141 ++++++++++++++ .../com/example/bigtable/BigtableHelper.java | 142 ++++++++++++++ .../src/main/webapp/WEB-INF/appengine-web.xml | 23 +++ .../main/webapp/WEB-INF/logging.properties | 13 ++ .../bigtable/src/main/webapp/WEB-INF/web.xml | 34 ++++ .../ee8/bigtable/src/main/webapp/bigtable.jsp | 32 +++ .../ee8/bigtable/src/main/webapp/favicon.ico | Bin 0 -> 1150 bytes .../bigtable/BigtableHelloWorldTests.java | 47 +++++ 15 files changed, 1051 insertions(+) create mode 100644 appengine-java21/ee8/bigtable/README.md create mode 100644 appengine-java21/ee8/bigtable/build.gradle create mode 100644 appengine-java21/ee8/bigtable/gradle/wrapper/gradle-wrapper.properties create mode 100755 appengine-java21/ee8/bigtable/gradlew create mode 100644 appengine-java21/ee8/bigtable/gradlew.bat create mode 100644 appengine-java21/ee8/bigtable/pom.xml create mode 100644 appengine-java21/ee8/bigtable/settings.gradle create mode 100644 appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelloWorld.java create mode 100644 appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelper.java create mode 100644 appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml create mode 100644 appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/logging.properties create mode 100644 appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/web.xml create mode 100644 appengine-java21/ee8/bigtable/src/main/webapp/bigtable.jsp create mode 100644 appengine-java21/ee8/bigtable/src/main/webapp/favicon.ico create mode 100644 appengine-java21/ee8/bigtable/src/test/java/com/example/bigtable/BigtableHelloWorldTests.java diff --git a/appengine-java21/ee8/bigtable/README.md b/appengine-java21/ee8/bigtable/README.md new file mode 100644 index 00000000000..14b255c472a --- /dev/null +++ b/appengine-java21/ee8/bigtable/README.md @@ -0,0 +1,59 @@ +Bigtable-hello-j21 +================= + + +Open in Cloud Shell + +Moves the Bigtable Hello World application to Google App Engine Standard for Java 21. + + +* [Java 21](http://www.oracle.com/technetwork/java/javase/downloads/index.html) +* [Maven](https://maven.apache.org/download.cgi) (at least 3.3.9) +* [Gradle](https://gradle.org) +* [Google Cloud CLI](https://cloud.google.com/cli/) (aka gcloud) + +Initialize the Google Cloud CLI using: + + gcloud init + + gcloud auth application-default login + +Then you need to [Create a Cloud Bigtable Instance](https://cloud.google.com/bigtable/docs/creating-instance) + + +## Using Maven + +### Run Locally + + mvn -Dbigtable.projectID=PROJECTID -Dbigtable.instanceID=INSTANCEID appengine:run + +### Deploy to App Engine Standard for Java 21 + + mvn -Dbigtable.projectID=PROJECTID -Dbigtable.instanceID=INSTANCEID package appengine:deploy + +### Run Integration Tests + + mvn -Dbigtable.projectID=PROJECTID -Dbigtable.instanceID=INSTANCEID verify + +## Using Gradle + +### Run Locally + + gradle -Dbigtable.projectID=PROJECTID -Dbigtable.instanceID=INSTANCEID appengineRun + +### Integration Tests & Deploy to App Engine Standard for Java 21 + + gradle -Dbigtable.projectID=PROJECTID -Dbigtable.instanceID=INSTANCEID appengineDeploy + +As you add / modify the source code (`src/main/java/...`) it's very useful to add +[unit testing](https://cloud.google.com/appengine/docs/java/tools/localunittesting) +to (`src/main/test/...`). The following resources are quite useful: + +* [JUnit4](http://junit.org/junit4/) +* [Mockito](http://mockito.org/) +* [Truth](http://google.github.io/truth/) + +### When done + +Cloud Bigtable Instances should be [deleted](https://cloud.google.com/bigtable/docs/deleting-instance) +when they are no longer being used as they use significant resources. diff --git a/appengine-java21/ee8/bigtable/build.gradle b/appengine-java21/ee8/bigtable/build.gradle new file mode 100644 index 00000000000..e8c123d086a --- /dev/null +++ b/appengine-java21/ee8/bigtable/build.gradle @@ -0,0 +1,113 @@ +// Copyright 2017 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. +// [START gradle] +buildscript { // Configuration for building + repositories { + jcenter() // Bintray's repository - a fast Maven Central mirror & more + mavenCentral() + } + dependencies { + classpath 'com.google.cloud.tools:appengine-gradle-plugin:2.5.0' + classpath 'org.akhikhl.gretty:gretty:+' + } +} + +apply plugin: 'java' +apply plugin: 'war' +apply plugin: 'org.akhikhl.gretty' // To get webappcopy +apply plugin: 'com.google.cloud.tools.appengine' + +group = 'com.example.google.cloud.bigtable' +version = '0.1-SNAPSHOT' + +sourceCompatibility = 21 +targetCompatibility = 21 + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +repositories { + maven { url "https://oss.sonatype.org/content/repositories/snapshots" } + jcenter() + mavenCentral() +} + +dependencies { + compile group: 'com.google.cloud.bigtable', name: 'bigtable-hbase-1.2', version:'1.0.0-pre3' + compile group: 'org.apache.hbase', name: 'hbase-client', version:'2.5.6' + compile group: 'io.netty', name: 'netty-tcnative-boringssl-static', version:'2.0.62.Final' + compile group: 'jstl', name: 'jstl', version:'1.2' + + providedCompile group: 'javax.servlet', name: 'javax.servlet-api', version:'3.1.0' + + testCompile group: 'com.google.truth', name: 'truth', version:'1.1.5' + testCompile group: 'junit', name: 'junit', version:'4.13.2' + testCompile group: 'org.mockito', name: 'mockito-core', version:'4.11.0' +} + +import org.apache.tools.ant.filters.ReplaceTokens +gretty { + contextPath = '/' + servletContainer = 'jetty9' + + jvmArgs = [ '-DBIGTABLE_PROJECT=' + System.getProperty("bigtable.projectID"), + '-DBIGTABLE_INSTANCE=' + System.getProperty("bigtable.instanceID")] + + webappCopy { + // Enable filtering on all xml files in WEB-INF + filesMatching "**/WEB-INF/*.xml", { FileCopyDetails fileDetails -> + logger.lifecycle 'File filtered: {}', fileDetails.path + filter (ReplaceTokens, tokens: [ + 'bigtable.projectID' : System.getProperty("bigtable.projectID"), + 'bigtable.instanceID': System.getProperty("bigtable.instanceID") + ]) + } + } +} + +// Always run unit tests +appengineDeploy.dependsOn test + +// [START model] +appengine { + run { + + } + deploy { // deploy configuration + stopPreviousVersion = true // default - stop the current version + promote = true // default - & make this the current version + } +} + +test { + useJUnit() + testLogging.showStandardStreams = true + + systemProperty 'BIGTABLE_PROJECT', System.getProperty("bigtable.projectID") + systemProperty 'BIGTABLE_INSTANCE',System.getProperty("bigtable.instanceID") + + beforeTest { descriptor -> + logger.lifecycle("test: " + descriptor + " Running") + } + + onOutput { descriptor, event -> + logger.lifecycle("test: " + descriptor + ": " + event.message ) + } + afterTest { descriptor, result -> + logger.lifecycle("test: " + descriptor + ": " + result ) + } +} +// [END model] +// [END gradle] diff --git a/appengine-java21/ee8/bigtable/gradle/wrapper/gradle-wrapper.properties b/appengine-java21/ee8/bigtable/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..6e82a0b51fb --- /dev/null +++ b/appengine-java21/ee8/bigtable/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Apr 03 21:11:48 PDT 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip diff --git a/appengine-java21/ee8/bigtable/gradlew b/appengine-java21/ee8/bigtable/gradlew new file mode 100755 index 00000000000..4453ccea33d --- /dev/null +++ b/appengine-java21/ee8/bigtable/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save ( ) { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/appengine-java21/ee8/bigtable/gradlew.bat b/appengine-java21/ee8/bigtable/gradlew.bat new file mode 100644 index 00000000000..e95643d6a2c --- /dev/null +++ b/appengine-java21/ee8/bigtable/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/appengine-java21/ee8/bigtable/pom.xml b/appengine-java21/ee8/bigtable/pom.xml new file mode 100644 index 00000000000..357e9125a5e --- /dev/null +++ b/appengine-java21/ee8/bigtable/pom.xml @@ -0,0 +1,184 @@ + + + + + 4.0.0 + war + 0.1-SNAPSHOT + + com.example.appengine + bigtable-hello-j21 + + + + com.google.cloud.samples + shared-configuration + 1.2.0 + + + + 21 + 21 + + YOUR_PROJECT_ID + YOUR_INSTANCE_ID + false + + + + + com.google.cloud.bigtable + + bigtable-hbase-1.x-hadoop + 2.12.0 + + + + + jakarta.servlet + jakarta.servlet-api + 6.1.0 + jar + provided + + + jstl + jstl + 1.2 + + + + + + com.google.truth + truth + 1.1.5 + test + + + + junit + junit + 4.13.2 + test + + + org.mockito + mockito-core + 4.11.0 + test + + + + + + ${project.build.directory}/${project.build.finalName}/WEB-INF/classes + + + + org.apache.maven.plugins + maven-resources-plugin + 3.3.1 + + UTF-8 + + @ + + false + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.4.0 + + true + + + + ${basedir}/src/main/webapp/WEB-INF + true + WEB-INF + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.2.2 + + + ${bigtable.projectID} + ${bigtable.instanceID} + + + + + + com.google.cloud.tools + appengine-maven-plugin + 2.8.0 + + GCLOUD_CONFIG + GCLOUD_CONFIG + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + + + org.apache.maven.plugins + maven-clean-plugin + 3.3.2 + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.4.1 + + + + [3.5.0,) + + + + + + + + + + snapshots-repo + https://oss.sonatype.org/content/repositories/snapshots + false + true + + + + diff --git a/appengine-java21/ee8/bigtable/settings.gradle b/appengine-java21/ee8/bigtable/settings.gradle new file mode 100644 index 00000000000..6584c995a81 --- /dev/null +++ b/appengine-java21/ee8/bigtable/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'bigtable-hello-j21' diff --git a/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelloWorld.java b/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelloWorld.java new file mode 100644 index 00000000000..3e01ab1791b --- /dev/null +++ b/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelloWorld.java @@ -0,0 +1,141 @@ +/* + * Copyright 2016 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.bigtable; + +import java.io.IOException; +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Admin; +import org.apache.hadoop.hbase.client.Connection; +import org.apache.hadoop.hbase.client.Get; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.ResultScanner; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.client.Table; +import org.apache.hadoop.hbase.util.Bytes; +// [START gae_java21_bigtable] + +/** + * A minimal application that connects to Cloud Bigtable using the native HBase API and performs + * some basic operations. + */ +public class BigtableHelloWorld { + + // Refer to table metadata names by byte array in the HBase API + private static final byte[] TABLE_NAME = Bytes.toBytes("Hello-Bigtable"); + private static final byte[] COLUMN_FAMILY_NAME = Bytes.toBytes("cf1"); + private static final byte[] COLUMN_NAME = Bytes.toBytes("greeting"); + + // Write some friendly greetings to Cloud Bigtable + private static final String[] GREETINGS = { + "Hello World!", "Hello Cloud Bigtable!", "Hello HBase!" + }; + + /** + * Create a table -- first time only. + * + * @param connection to Bigtable + * @return the status + */ + public static String create(Connection connection) { + try { + // The admin API lets us create, manage and delete tables + Admin admin = connection.getAdmin(); + + // Create a table with a single column family + HTableDescriptor descriptor = new HTableDescriptor(TableName.valueOf(TABLE_NAME)); + descriptor.addFamily(new HColumnDescriptor(COLUMN_FAMILY_NAME)); + + admin.createTable(descriptor); + } catch (IOException e) { + return "Table exists."; + } + return "Create table " + Bytes.toString(TABLE_NAME); + } + + /** Connects to Cloud Bigtable, runs some basic operations and prints the results. */ + public static String doHelloWorld() { + + StringBuilder result = new StringBuilder(); + + // Create the Bigtable connection, use try-with-resources to make sure it gets closed + Connection connection = BigtableHelper.getConnection(); + result.append(create(connection)); + result.append("

"); + try (Table table = connection.getTable(TableName.valueOf(TABLE_NAME))) { + + // Retrieve the table we just created so we can do some reads and writes + + // Write some rows to the table + result.append("Write some greetings to the table
"); + for (int i = 0; i < GREETINGS.length; i++) { + // Each row has a unique row key. + // + // Note: This example uses sequential numeric IDs for simplicity, but + // this can result in poor performance in a production application. + // Since rows are stored in sorted order by key, sequential keys can + // result in poor distribution of operations across nodes. + // + // For more information about how to design a Bigtable schema for the + // best performance, see the documentation: + // + // https://cloud.google.com/bigtable/docs/schema-design + String rowKey = "greeting" + i; + + // Put a single row into the table. We could also pass a list of Puts to write a batch. + Put put = new Put(Bytes.toBytes(rowKey)); + put.addColumn(COLUMN_FAMILY_NAME, COLUMN_NAME, Bytes.toBytes(GREETINGS[i])); + table.put(put); + } + + // Get the first greeting by row key + String rowKey = "greeting0"; + Result getResult = table.get(new Get(Bytes.toBytes(rowKey))); + String greeting = Bytes.toString(getResult.getValue(COLUMN_FAMILY_NAME, COLUMN_NAME)); + result.append("Get a single greeting by row key
"); + + result.append(" "); + result.append(rowKey); + result.append("= "); + result.append(greeting); + result.append("
"); + + // Now scan across all rows. + Scan scan = new Scan(); + + result.append("Scan for all greetings:"); + ResultScanner scanner = table.getScanner(scan); + for (Result row : scanner) { + byte[] valueBytes = row.getValue(COLUMN_FAMILY_NAME, COLUMN_NAME); + result.append(" "); + result.append(Bytes.toString(valueBytes)); + result.append("
"); + } + + } catch (IOException e) { + result.append("Exception while running HelloWorld: " + e.getMessage() + "
"); + result.append(e.toString()); + return result.toString(); + } + + return result.toString(); + } +} +// [END gae_java21_bigtable] diff --git a/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelper.java b/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelper.java new file mode 100644 index 00000000000..e81e3a1f6a4 --- /dev/null +++ b/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelper.java @@ -0,0 +1,142 @@ +/* + * Copyright 2016 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.bigtable; + +import com.google.cloud.bigtable.hbase.BigtableConfiguration; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; +import jakarta.servlet.annotation.WebListener; +import java.io.IOException; +import org.apache.hadoop.hbase.client.Connection; + +/** + * BigtableHelper, a ServletContextListener, is setup in web.xml to run before a jsp is run. Project + * / Instance settings can be passed as an Environment Variable, a System Property, or set in + * web.xml from a context-param + */ +@WebListener +public class BigtableHelper implements ServletContextListener { + + private static String PROJECT_ID; + private static String INSTANCE_ID; + + // The initial connection to Cloud Bigtable is an expensive operation -- We cache this Connection + // to speed things up. For this sample, keeping them here is a good idea, for + // your application, you may wish to keep this somewhere else. + private static Connection connection = null; // The authenticated connection + + private static ServletContext sc; + + /** Connect will establish the connection to Cloud Bigtable. */ + public static void connect() throws IOException { + + if (PROJECT_ID == null || INSTANCE_ID == null) { + if (sc != null) { + sc.log("environment variables BIGTABLE_PROJECT, and BIGTABLE_INSTANCE need to be defined."); + } + return; + } + + connection = BigtableConfiguration.connect(PROJECT_ID, INSTANCE_ID); + } + + /** + * Get the shared connection to Cloud Bigtable. + * + * @return the connection + */ + public static Connection getConnection() { + if (connection == null) { + try { + connect(); + } catch (IOException e) { + if (sc != null) { + sc.log("connect ", e); + } + } + } + if (connection == null) { + if (sc != null) { + sc.log("BigtableHelper-No Connection"); + } + } + return connection; + } + + @Override + public void contextInitialized(ServletContextEvent event) { + // This will be invoked as part of a warmup request, or the first user + // request if no warmup request was invoked. + + if (event != null) { + sc = event.getServletContext(); + if (PROJECT_ID == null) { + PROJECT_ID = sc.getInitParameter("BIGTABLE_PROJECT"); + } + if (INSTANCE_ID == null) { + INSTANCE_ID = sc.getInitParameter("BIGTABLE_INSTANCE"); + } + } + + if (PROJECT_ID != null && PROJECT_ID.startsWith("@")) { + PROJECT_ID = null; + } + if (INSTANCE_ID != null && INSTANCE_ID.startsWith("@")) { + INSTANCE_ID = null; + } + + if (PROJECT_ID == null) { + PROJECT_ID = System.getProperty("bigtable.projectID"); + } + if (INSTANCE_ID == null) { + INSTANCE_ID = System.getProperty("bigtable.instanceID"); + } + + try { + connect(); + } catch (IOException e) { + if (sc != null) { + sc.log("BigtableHelper - connect ", e); + } + } + if (connection == null) { + if (sc != null) { + sc.log("BigtableHelper-No Connection"); + } + } + if (sc != null) { + sc.log("ctx Initialized: " + PROJECT_ID + " " + INSTANCE_ID); + } + } + + @Override + public void contextDestroyed(ServletContextEvent event) { + // App Engine does not currently invoke this method. + if (connection == null) { + return; + } + try { + connection.close(); + } catch (IOException io) { + if (sc != null) { + sc.log("contextDestroyed ", io); + } + } + connection = null; + } +} diff --git a/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml new file mode 100644 index 00000000000..70835f37a56 --- /dev/null +++ b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml @@ -0,0 +1,23 @@ + + + + true + java21 + + + + + + + diff --git a/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/logging.properties b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/logging.properties new file mode 100644 index 00000000000..0c2ea51bc6d --- /dev/null +++ b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/logging.properties @@ -0,0 +1,13 @@ +# A default java.util.logging configuration. +# (All App Engine logging is through java.util.logging by default). +# +# To use this configuration, copy it into your application's WEB-INF +# folder and add the following to your appengine-web.xml: +# +# +# +# +# + +# Set the default logging level for all loggers to WARNING +.level = WARNING diff --git a/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/web.xml b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..51a06633f25 --- /dev/null +++ b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,34 @@ + + + + + + bigtable.jsp + + + BIGTABLE_PROJECT + @bigtable.projectID@ + + + BIGTABLE_INSTANCE + @bigtable.instanceID@ + + diff --git a/appengine-java21/ee8/bigtable/src/main/webapp/bigtable.jsp b/appengine-java21/ee8/bigtable/src/main/webapp/bigtable.jsp new file mode 100644 index 00000000000..c26ebb5da83 --- /dev/null +++ b/appengine-java21/ee8/bigtable/src/main/webapp/bigtable.jsp @@ -0,0 +1,32 @@ + +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ page import="com.example.bigtable.BigtableHelloWorld" %> + +<%-- + ~ Copyright 2017 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. + --%> + + + + + Hello App Engine Standard using Java 8 + + +

Hello App Engine -- Standard for Java 21!

+ +

This is <%= BigtableHelloWorld.doHelloWorld() %>. + + + diff --git a/appengine-java21/ee8/bigtable/src/main/webapp/favicon.ico b/appengine-java21/ee8/bigtable/src/main/webapp/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..0062ab413e73fa137f91cc1b082ce6a9bc992730 GIT binary patch literal 1150 zcmchVT}YE*6vvO#ObKxkm}F29kx=MGBotCtksqk6T__r47lF2m6b%yb3oXOSIbYlS zT0@&?=KPkK%d$<~me%IfxfOnO(T!aM-B`iXL)@7O-l`DN1e2iD~XBziRG#kh#!R zlB8E8it@c6mm2KdQt4SrtcazQq9_WzNfg|g7q>oV8HRho0@vImRu-q>c1&T}ZNrEn z8w_M!@>p|P*lUL-1J(u!w6ahr(+Hi9ZooSBf?u?cW7TQJtD)!6ceg^Ls^;x8CJa_y zf%=*VO;Z1ys*4oKB@ovui@-u#Hq6{5exOLqtJr&1mYlE|hcK)zgn3L4omPc*wSr%= z8_+Kc`Kie`Q0Tpfu$IM8wNYDwH_b8_xGb!Fa=_S@3&Y(2n7fMcvbUY_wU~QvMAZdK z^0GqD1uKoB1e>V`i?b%)Jv)KVjGx!#!(1kYZAgyE(SB%Kt6uq5SN`+}7YLJM^E%zeeoan^L zM+er|To@bdfV#d4+`}^7JU$FVz3jW7t&A1oPE$#Oia#jM!CG;cH`F9xacU4>zbwNv z(v8_^Bi`xc$PJ;B0@aimxf5om`sBbn^J*!q@>tZRP~WWpI{ozearr={bfhEqd}}Jv zK>=z^KlB$XBx>VDdCR&2bjiYnIr*n?DSu{fx8Qypof#;IMom2B2sJKw|89xT^OJ2e zEr^toK%ZJ)g{BNoPa4xBd`WiX!TwTk{wUFga8*Axhs;;~iN0-fp|&9>`oXlnwito? E4Z4s|oB#j- literal 0 HcmV?d00001 diff --git a/appengine-java21/ee8/bigtable/src/test/java/com/example/bigtable/BigtableHelloWorldTests.java b/appengine-java21/ee8/bigtable/src/test/java/com/example/bigtable/BigtableHelloWorldTests.java new file mode 100644 index 00000000000..7b13aa67e2f --- /dev/null +++ b/appengine-java21/ee8/bigtable/src/test/java/com/example/bigtable/BigtableHelloWorldTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2016 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.bigtable; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link BigtableHelloWorld}. */ +@RunWith(JUnit4.class) +public class BigtableHelloWorldTests { + + private BigtableHelper helper; + + @Before + public void setUp() throws Exception { + helper = new BigtableHelper(); + helper.contextInitialized(null); + } + + @Test + public void bigtable_test() { + String result = BigtableHelloWorld.doHelloWorld(); + assertThat(result).contains("Write some greetings to the table"); + assertThat(result).contains("Get a single greeting by row key"); + assertThat(result).contains("greeting0= Hello World!"); + assertThat(result).contains("Hello Cloud Bigtable!"); + assertThat(result).contains("Hello HBase!"); + } +} From 18ed4cacbb90d180cd492531f09fb532eb405b4d Mon Sep 17 00:00:00 2001 From: Alan Ramirez Herrera Date: Mon, 1 Sep 2025 21:11:21 +0000 Subject: [PATCH 2/6] fix: add license header to settings.gradle --- appengine-java21/ee8/bigtable/settings.gradle | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/appengine-java21/ee8/bigtable/settings.gradle b/appengine-java21/ee8/bigtable/settings.gradle index 6584c995a81..f77c416bd3a 100644 --- a/appengine-java21/ee8/bigtable/settings.gradle +++ b/appengine-java21/ee8/bigtable/settings.gradle @@ -1 +1,14 @@ +// Copyright 2017 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. rootProject.name = 'bigtable-hello-j21' From 5104119334ca64b98e2bc2cd8c0666923e544f0b Mon Sep 17 00:00:00 2001 From: Alan Ramirez Herrera Date: Wed, 3 Sep 2025 20:36:19 +0000 Subject: [PATCH 3/6] chore: set app-engine-apis to true --- .../ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml index 70835f37a56..44515ee548d 100644 --- a/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml +++ b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml @@ -12,8 +12,8 @@ limitations under the License. --> - true java21 + true From 089d15e2d41e451c69a8aff163069f2ed382d749 Mon Sep 17 00:00:00 2001 From: Alan Ramirez Herrera Date: Wed, 10 Sep 2025 17:44:52 +0000 Subject: [PATCH 4/6] chore: use EE8 instead of EE10 --- appengine-java21/ee8/bigtable/pom.xml | 12 +++++++++--- .../java/com/example/bigtable/BigtableHelper.java | 8 ++++---- .../src/main/webapp/WEB-INF/appengine-web.xml | 1 + .../ee8/bigtable/src/main/webapp/WEB-INF/web.xml | 1 + 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/appengine-java21/ee8/bigtable/pom.xml b/appengine-java21/ee8/bigtable/pom.xml index 357e9125a5e..82dbfc2c4bc 100644 --- a/appengine-java21/ee8/bigtable/pom.xml +++ b/appengine-java21/ee8/bigtable/pom.xml @@ -52,9 +52,9 @@ limitations under the License. - jakarta.servlet - jakarta.servlet-api - 6.1.0 + javax.servlet + javax.servlet-api + 3.1.0 jar provided @@ -123,6 +123,12 @@ limitations under the License. + + org.jacoco + jacoco-maven-plugin + 0.8.13 + + org.apache.maven.plugins maven-failsafe-plugin diff --git a/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelper.java b/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelper.java index e81e3a1f6a4..dfcbd1e6352 100644 --- a/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelper.java +++ b/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelper.java @@ -17,11 +17,11 @@ package com.example.bigtable; import com.google.cloud.bigtable.hbase.BigtableConfiguration; -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletContextEvent; -import jakarta.servlet.ServletContextListener; -import jakarta.servlet.annotation.WebListener; import java.io.IOException; +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; import org.apache.hadoop.hbase.client.Connection; /** diff --git a/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml index 44515ee548d..2209fe610cd 100644 --- a/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml +++ b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/appengine-web.xml @@ -16,6 +16,7 @@ true + diff --git a/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/web.xml b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/web.xml index 51a06633f25..2fecfb4115c 100644 --- a/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/web.xml +++ b/appengine-java21/ee8/bigtable/src/main/webapp/WEB-INF/web.xml @@ -31,4 +31,5 @@ limitations under the License. BIGTABLE_INSTANCE @bigtable.instanceID@ + From 10bd477f2a88df8f046934e8d2e955af5f4d198c Mon Sep 17 00:00:00 2001 From: Alan Ramirez Herrera Date: Wed, 10 Sep 2025 22:01:10 +0000 Subject: [PATCH 5/6] chore: upgrade dependencies --- appengine-java21/ee8/bigtable/README.md | 2 +- appengine-java21/ee8/bigtable/build.gradle | 6 +++--- appengine-java21/ee8/bigtable/pom.xml | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/appengine-java21/ee8/bigtable/README.md b/appengine-java21/ee8/bigtable/README.md index 14b255c472a..c4df5547773 100644 --- a/appengine-java21/ee8/bigtable/README.md +++ b/appengine-java21/ee8/bigtable/README.md @@ -1,7 +1,7 @@ Bigtable-hello-j21 ================= - + Open in Cloud Shell Moves the Bigtable Hello World application to Google App Engine Standard for Java 21. diff --git a/appengine-java21/ee8/bigtable/build.gradle b/appengine-java21/ee8/bigtable/build.gradle index e8c123d086a..a416512796a 100644 --- a/appengine-java21/ee8/bigtable/build.gradle +++ b/appengine-java21/ee8/bigtable/build.gradle @@ -48,11 +48,11 @@ dependencies { compile group: 'com.google.cloud.bigtable', name: 'bigtable-hbase-1.2', version:'1.0.0-pre3' compile group: 'org.apache.hbase', name: 'hbase-client', version:'2.5.6' compile group: 'io.netty', name: 'netty-tcnative-boringssl-static', version:'2.0.62.Final' - compile group: 'jstl', name: 'jstl', version:'1.2' + compile group: 'jakarta.servlet.jsp.jstl', name: 'jakarta.servlet.jsp.jstl-api', version:'1.2.7' - providedCompile group: 'javax.servlet', name: 'javax.servlet-api', version:'3.1.0' + providedCompile group: 'jakarta.servlet', name: 'jakarta.servlet-api', version:'4.0.4' - testCompile group: 'com.google.truth', name: 'truth', version:'1.1.5' + testCompile group: 'com.google.truth', name: 'truth', version:'1.4.4' testCompile group: 'junit', name: 'junit', version:'4.13.2' testCompile group: 'org.mockito', name: 'mockito-core', version:'4.11.0' } diff --git a/appengine-java21/ee8/bigtable/pom.xml b/appengine-java21/ee8/bigtable/pom.xml index 82dbfc2c4bc..8a52e798a79 100644 --- a/appengine-java21/ee8/bigtable/pom.xml +++ b/appengine-java21/ee8/bigtable/pom.xml @@ -52,16 +52,16 @@ limitations under the License. - javax.servlet - javax.servlet-api - 3.1.0 + jakarta.servlet + jakarta.servlet-api + 4.0.4 jar provided - jstl - jstl - 1.2 + jakarta.servlet.jsp.jstl + jakarta.servlet.jsp.jstl-api + 1.2.7 @@ -69,7 +69,7 @@ limitations under the License. com.google.truth truth - 1.1.5 + 1.4.4 test From 63bdc42e41feb27990adacc38dd9e6b1103ef2d5 Mon Sep 17 00:00:00 2001 From: Alan Ramirez Herrera Date: Thu, 11 Sep 2025 17:44:40 +0000 Subject: [PATCH 6/6] fix: region tag names and remove java 8 reference --- appengine-java21/ee8/bigtable/build.gradle | 8 ++++---- .../java/com/example/bigtable/BigtableHelloWorld.java | 5 +++-- .../ee8/bigtable/src/main/webapp/bigtable.jsp | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/appengine-java21/ee8/bigtable/build.gradle b/appengine-java21/ee8/bigtable/build.gradle index a416512796a..999819d2758 100644 --- a/appengine-java21/ee8/bigtable/build.gradle +++ b/appengine-java21/ee8/bigtable/build.gradle @@ -11,7 +11,7 @@ // 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. -// [START gradle] +// [START gae_java21_bigtable_gradle_file] buildscript { // Configuration for building repositories { jcenter() // Bintray's repository - a fast Maven Central mirror & more @@ -80,7 +80,7 @@ gretty { // Always run unit tests appengineDeploy.dependsOn test -// [START model] +// [START gae_java21_bigtable_gradle_model] appengine { run { @@ -109,5 +109,5 @@ test { logger.lifecycle("test: " + descriptor + ": " + result ) } } -// [END model] -// [END gradle] +// [END gae_java21_bigtable_gradle_model] +// [END gae_java21_bigtable_gradle_file] diff --git a/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelloWorld.java b/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelloWorld.java index 3e01ab1791b..3d6e07dae5a 100644 --- a/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelloWorld.java +++ b/appengine-java21/ee8/bigtable/src/main/java/com/example/bigtable/BigtableHelloWorld.java @@ -17,6 +17,8 @@ package com.example.bigtable; +// [START gae_java21_bigtable_helloworld] + import java.io.IOException; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HTableDescriptor; @@ -30,7 +32,6 @@ import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.util.Bytes; -// [START gae_java21_bigtable] /** * A minimal application that connects to Cloud Bigtable using the native HBase API and performs @@ -138,4 +139,4 @@ public static String doHelloWorld() { return result.toString(); } } -// [END gae_java21_bigtable] +// [END gae_java21_bigtable_helloworld] diff --git a/appengine-java21/ee8/bigtable/src/main/webapp/bigtable.jsp b/appengine-java21/ee8/bigtable/src/main/webapp/bigtable.jsp index c26ebb5da83..88a040051e6 100644 --- a/appengine-java21/ee8/bigtable/src/main/webapp/bigtable.jsp +++ b/appengine-java21/ee8/bigtable/src/main/webapp/bigtable.jsp @@ -21,7 +21,7 @@ - Hello App Engine Standard using Java 8 + Hello App Engine Standard using Java 21

Hello App Engine -- Standard for Java 21!