问题
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.
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/56828520/java-lang-module-resolutionexception-when-adding-google-cloud-datastore-dependen