Skip to content

fix(appengine): removing obsolete symlink from java 8 on java 11 bundle services#10272

Draft
Kef131 wants to merge 1 commit into
GoogleCloudPlatform:mainfrom
Kef131:fix-java8-symlink-on-java11bundleservices
Draft

fix(appengine): removing obsolete symlink from java 8 on java 11 bundle services#10272
Kef131 wants to merge 1 commit into
GoogleCloudPlatform:mainfrom
Kef131:fix-java8-symlink-on-java11bundleservices

Conversation

@Kef131
Copy link
Copy Markdown

@Kef131 Kef131 commented May 20, 2026

Description

Fixes #10242
Internal: b/496677589
Same case as previous #10270

This PR dereferences the symbolic links in the Java 11 App Engine bundled services module (appengine-java11-bundled-services) that previously pointed to the deleted/legacy appengine-java8 directory. By making these files self-contained, this module can run independently without relying on Java 8 code.

Additionally, this PR adds the missing JSTL dependency to the Java 11 pom.xml to resolve JSP runtime compilation errors (JasperException / ClassNotFoundException for guestbook_jsp) when running the development server locally with mvn appengine:run.

This PR dereferenced 32 Symbolic links on appengine-java11-bundled-services/datastore

Checklist

  • I have followed Sample Format Guide
  • pom.xml parent set to latest shared-configuration
  • Appropriate changes to README are included in PR
  • These samples need a new API enabled in testing projects to pass (let us know which ones)
  • These samples need a new/updated env vars in testing projects set to pass (let us know which ones)
  • Tests pass: mvn clean verify required
  • Lint passes: mvn -P lint checkstyle:check required
  • Static Analysis: mvn -P lint clean compile pmd:cpd-check spotbugs:check advisory only
  • This sample adds a new sample directory, and I updated the CODEOWNERS file with the codeowners for this sample
  • This sample adds a new Product API, and I updated the Blunderbuss issue/PR auto-assigner with the codeowners for this sample
  • Please merge this PR for me once it is approved

@product-auto-label product-auto-label Bot added samples Issues that are directly related to samples. api: appengine Issues related to the App Engine Admin API API. labels May 20, 2026
@Kef131 Kef131 changed the title Fix broken symlinks in Java 11 bundle services fix(appengine): removing obsolete symlink from java 8 on java 11 bundle services May 20, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request migrates the Datastore sample code to the App Engine Java 11 runtime. The review identified several critical security vulnerabilities, specifically Cross-Site Scripting (XSS) risks in the ListPeopleServlet and guestbook.jsp, which require input escaping. Additionally, a potential runtime exception in MetadataNamespacesTest was flagged regarding empty filter lists. The feedback also suggests several refactoring opportunities to improve code conciseness using Java Streams and recommends addressing test flakiness in GuestbookTest by ensuring proper isolation of static state.

I am having trouble creating individual review comments. Click here to see my feedback.

appengine-java11-bundled-services/datastore/src/main/java/com/example/appengine/ListPeopleServlet.java (81)

security-high high

The entity property name is written directly to the HTML output without escaping. This is a potential Cross-Site Scripting (XSS) vulnerability if the names can contain HTML characters. You should escape the property before writing it to the response. You can use a library like Guava's HtmlEscapers for this, since Guava is already a dependency.

      w.println("<li>" + com.google.common.html.HtmlEscapers.htmlEscaper().escape((String) entity.getProperty("name")) + "</li>");

appengine-java11-bundled-services/datastore/src/main/webapp/guestbook.jsp (28)

security-high high

The greeting.content is rendered directly to the page without escaping. This can lead to a Cross-Site Scripting (XSS) vulnerability if the content contains malicious HTML or JavaScript. You should use JSTL's <c:out> tag to escape the content.

        <c:out value="${greeting.content}"/>

appengine-java11-bundled-services/datastore/src/test/java/com/example/appengine/MetadataNamespacesTest.java (124)

high

Calling CompositeFilterOperator.and() with an empty list of filters will throw an IllegalArgumentException. You should only set the filter if the subFilters list is not empty. Also, if there's only one filter, you don't need to wrap it in a CompositeFilter.

    if (!subFilters.isEmpty()) {
      if (subFilters.size() == 1) {
        q.setFilter(subFilters.get(0));
      } else {
        q.setFilter(CompositeFilterOperator.and(subFilters));
      }
    }

appengine-java11-bundled-services/datastore/src/main/java/com/example/appengine/AbstractGuestbook.java (65-69)

medium

This loop can be simplified using Java Streams and Guava's ImmutableList.toImmutableList() collector for a more concise and functional approach.

    return listGreetingEntities(datastore).stream()
        .map(Greeting::create)
        .collect(com.google.common.collect.ImmutableList.toImmutableList());

appengine-java11-bundled-services/datastore/src/main/java/com/example/appengine/StartupServlet.java (109-115)

medium

This entity creation and population logic can be simplified using Java Streams for a more modern and functional style.

    java.util.List<Entity> people = US_PRESIDENTS.stream()
        .map(name -> {
          Entity person = new Entity(PERSON_ENTITY);
          person.setProperty(NAME_PROPERTY, name);
          return person;
        })
        .collect(java.util.stream.Collectors.toList());
    datastore.put(people);

appengine-java11-bundled-services/datastore/src/test/java/com/example/appengine/GuestbookTest.java (43-44)

medium

The static fields newJobCounter and existingJobCounter can lead to flaky tests, as their state is shared across test executions within the same JVM run. This can cause tests to interfere with each other.

To ensure test isolation, you should reset these counters before each test, for example in the setUp() method:

@Before
public void setUp() throws Exception {
    helper.setUp();
    CustomHighRepJobPolicy.newJobCounter = 0;
    CustomHighRepJobPolicy.existingJobCounter = 0;
    clock = new FakeClock();
    guestbookUnderTest = new Guestbook(clock);
}

appengine-java11-bundled-services/datastore/src/test/java/com/example/appengine/MetadataNamespacesTest.java (127-135)

medium

This logic for collecting query results can be simplified using Java Streams for a more concise and functional approach.

    // Build list of query results
    return ds.prepare(q).asQueryResultIterable().stream()
        .map(e -> Entities.getNamespaceFromNamespaceKey(e.getKey()))
        .collect(java.util.stream.Collectors.toList());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: appengine Issues related to the App Engine Admin API API. samples Issues that are directly related to samples.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GAE samples are pointing to deleted java8 code, we need to dereference from old version.

1 participant