0

I have a modular jersey based microservice running on JDK 11. It deploys fine to Google App Engine. The code can be downloaded here (or clone the main project and switch to the 3.1 tag): https://github.com/Leejjon/SimpleJerseyService/releases/tag/3.1

Now I want to add access to the Google Cloud Datastore API (which worked on my previous non modular Java 8 project). So I add the maven dependency:

<dependency>
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-datastore</artifactId>
   <version>1.80.0</version>
</dependency>

And I add requires google.cloud.datastore; to my module-info.java.

A mvn clean install runs fine but when I run it via mvn exec:exec or java -p simple-service-1.0-SNAPSHOT.jar;appengine-staging/ -m myModule/com.example.Main localhost

I get:

Error occurred during initialization of boot layer
java.lang.module.ResolutionException: Modules grpc.context and grpc.api export package io.grpc to module org.apache.httpcomponents.httpclient

Is there anything I can do in my module-info.java to fix this problem?

After reading posts such as: https://blog.codefx.org/java/java-9-migration-guide/#Split-Packages https://blog.codefx.org/java/jsr-305-java-9/#Modular-Project Modules A and B export package some.package to module C in Java 9

I'm suspecting this google-cloud-datastore library just isn't ready for the Java Module System. I will post an issue on the Google Cloud Client API github refering to this stackoverflow post.

Leejjon
  • 680
  • 2
  • 7
  • 24

2 Answers2

0

Until Google adds valid module-info.java files to their google-cloud-datastore and google-cloud-core maven dependencies (I reported an issue on their github here), the workaround is to use the old classpath.

In the case of my project, change the configuration of the exec-maven-plugin from:

<configuration>
  <executable>java</executable>
  <arguments>
    <argument>-p</argument> <!-- or -p  -->
    <!-- automatically creates the modulepath using all project dependencies,
                             also adding the project build directory -->
    <modulepath/>
    <argument>-m</argument> <!-- or -m -->
    <argument>myModule/com.example.Main</argument>
    <argument>localhost</argument>
  </arguments>
</configuration>

to

<configuration>
    <executable>java</executable>
    <arguments>
        <argument>-classpath</argument>
        <!-- automatically creates the classpath using all project dependencies,
             also adding the project build directory -->
        <classpath/>
        <argument>com.example.Main</argument>
        <argument>localhost</argument>
    </arguments>
</configuration>

Using mvn -X exec:exec will show the full java command which includes all the required jars. The entire java command will be super long like this pastebin.

Leejjon
  • 680
  • 2
  • 7
  • 24
0

pmakani from github managed to "fix" my project by excluding dependencies:

<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-datastore</artifactId>
<version>1.80.0</version>
<exclusions>
   <exclusion>
       <groupId>com.google.code.findbugs</groupId>
       <artifactId>jsr305</artifactId>
   </exclusion>
   <exclusion>
       <groupId>io.grpc</groupId>
       <artifactId>grpc-core</artifactId>
   </exclusion>
</exclusions>
</dependency>

Accessing the datastore seems to work, however the log still contains errors like: java.lang.reflect.InaccessibleObjectException: Unable to make field protected volatile java.io.InputStream java.io.FilterInputStream.in accessible: module java.base does not "opens java.io" to module data

Full log: https://pastebin.com/e431R7pW

I suppose Google should still make their gcloud libs (and all the dependencies they depend on) modular.

Leejjon
  • 680
  • 2
  • 7
  • 24