GoogleCloudPlatform / cloud-opensource-java

Tools for detecting and avoiding linkage errors in GCP open source projects
Apache License 2.0
155 stars 74 forks source link

In JLBP-19 add a comment on how to use both module path and class path at the same time #1898

Open suztomo opened 3 years ago

suztomo commented 3 years ago

https://jlbp.dev/JLBP-19 says

If classes from the same package appear in Maven artifacts with different group IDs or different artifact IDs, it is easy to construct a classpath that splits packages. This is a problem even if individual classes do not overlap. For example, the google-cloud-vision Java API client places protobufs in com.google.api.grpc:proto-google-cloud-vision-v1 and gRPC stubs in com.google.api.grpc:grpc-google-cloud-vision-v1. Since both artifacts contain classes in the com.google.cloud.vision.v1 package, these two artifacts cannot be used together after Java 8.

If users choose to place these split-package libraries in class path rather than module path, they can use the libraries in Java 11.

ref https://blog.joda.org/2018/03/jpms-negative-benefits.html

elharo commented 3 years ago

How would this be done?

suztomo commented 3 years ago

I came up with an example. Let's say you have a module "com.greetings" that depends on an automatic module "proto.google.cloud.vision.v1". The module-info.java would look like this:

module com.greetings {
  requires org.astro;
  requires proto.google.cloud.vision.v1;
}

The automatic module comes from Java 8's JAR file "proto-google-cloud-vision-v1-1.100.10.jar" in module path. The JAR file uses classes from protobuf. We can use protobuf-java in the class path:

suztomo-macbookpro44% java \
    --module-path mods:jars/proto-google-cloud-vision-v1-1.100.10.jar \
    --class-path jars/protobuf-java-3.14.0.jar \
    -m com.greetings/com.greetings.Main

Now this command uses both module path and class path. In JPMS the packages (and classes) in the JAR files in the class path are in the "unnamed module". In this case, the classes in protobuf-java are in the unnamed module. Classes in a normal module cannot reference classes in unnamed modules. Classes in automatic module can reference it.

(Note that com.greetings.Main does not directly reference classes in protobuf-java)

My memo: https://gist.github.com/suztomo/ad537e4c921b0261c10e017f54518599

Question: how does this apply to Maven's pom.xml / Gradle's build.gradle?

suztomo commented 3 years ago

Population of affected users. (check report).

Library owners to document what's (undesirable) workaround.