3

I am compiling my legacy source code using JDK 9.0.1 as follows:

javac --add-modules=java.base,java.xml.ws -cp lib\jsr305.jar;lib\javax.annotation-api-1.2.jar TestJava.java

It gives an error because the annotations defined in jsr305.jar are not visible due to split module issue. The error is as follows:

TestJava.java:3: error: cannot find symbol
import javax.annotation.Nonnull;
                       ^
  symbol:   class Nonnull
  location: package javax.annotation

Here the module java.xml.ws.annotation is getting loaded since it is required for java.xml.ws. So it is ignoring the types in jsr305.jar. I don't want this module to be loaded but refer all its annotation types from javax.annotation-api-1.2.jar. I don't want to do --patch-module either because it would break in future releases.

If I use --limit-module=java.xml.ws.annotation it gives the same error. If I remove java.xml.ws from -add-modules, it compiles successfully but I need to export few APIs from it so can't remove it. Is there any way I can load module java.xml.ws but not java.xml.ws.annotation?

EDIT : I think I have added some confusion by giving an example of split between java.xml.ws.annotaion and jsr305.jar. Though it's my actual problem, I am more interested in knowing - can I avoid loading a transitively dependent module, say loading java.xml.ws without loading java.xml.ws.annotation? As per my understanding in JEP 261 it says,

--limit-modules <module>(,<module>)*

where <module> is a module name. The effect of this option is to limit the observable modules to those in the transitive closure of the named modules plus the main module, if any, plus any further modules specified via the --add-modules option.

So, why isn't --limit-module preventing java.xml.ws.annotation from loading?

keenUser
  • 1,279
  • 3
  • 16
  • 33
  • 1
    *If I remove java.xml.ws from `--add-modules`*, what APIs are there still needed for it? I would suggest looking forward in this direction if this is temporary or else be moving completely to [javaee's `javax.annotation`](https://stackoverflow.com/a/46502132/1746118) – Naman Nov 13 '17 at 07:14
  • You are right. The plan is remove all the deprecated APIs and move to modular code base. But that would take quite some time and before that, I would like to build and test entire application (it's huge !!) on java 9. Looking for a go-ahead as of now to pass through compilation errors at least. – keenUser Nov 13 '17 at 07:20
  • *I don't want to do --patch-module either because it would break in future releases.* I thought you were looking for something that might be long term. – Naman Nov 13 '17 at 07:22
  • I was really hoping to get this working with classpath (I already have both jars on classpath), also willing to know how to avoid loading such transitive dependency. Also, I would try to minimize my work in future, where class level changes would be time consuming at this point rather than changing some JVM params. – keenUser Nov 13 '17 at 07:39
  • 1
    On that note, it is really unclear to me in terms of what your goal is currently and how are you planning to migrate to Java9 as well? Maybe showing what all code is impacted in the above scenarios might help anyone to help you further. For example, what fails when you remove `--add-modules=java.base,java.xml.ws` from compilation command in the question? Classpath dependencies shouldn't result in split packages anyway. @keenUser – Naman Nov 13 '17 at 07:39
  • 1
    The scenario in the question is hopeless as the javax.annotation.* classes are in module javax.xml.ws.annotation, jsr305.jar, and javax.annotation-api-1.2.jar. Are you using the web services APIs? If so then the simplest would be to just download the standalone version and deploy on the class path. Links and all details on this topic can be found in: https://bugs.openjdk.java.net/browse/JDK-8189188 – Alan Bateman Nov 13 '17 at 08:07
  • Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. – Naman Nov 13 '17 at 11:01
  • @nullpointer - Please see the edit. Thanks. – keenUser Nov 13 '17 at 15:46

1 Answers1

2

I know of no way to prevent resolution of a transitive dependency.

Short-term fix

You should be able to make it work by patching the module with --patch-module java.xml.ws=lib\jsr305.jar:lib\javax.annotation-api-1.2.jar. My opinion: If you just want to get your build working on Java 9, that is a good choice. It's a little dubious but still acceptable if you want to use it in production.

If you're worried about long-term compatibility:

  • I don't think --patch-module will disappear any time soon - do you have a source for that?
  • I'm pretty sure java.xml.ws will be removed quite soon - it is already deprecated for removal.

In your place I'd worry about the module more than about patching it.

Long-term solution

So for a long-term solution you should remove your dependency on java.xml.ws. JDK-8189188 has a section on this (with lots of links that I was too lazy to copy):

The Reference Implementations (RIs) of JAX-WS and JAXB are a good starting point because they are complete replacements for the java.xml.ws and java.xml.bind modules in JDK 9. The RIs are available as Maven artifacts: (note that they must be deployed on the classpath)

  • com.sun.xml.ws : jaxws-ri (JAX-WS, plus SAAJ and Web Services Metadata)
  • com.sun.xml.bind : jaxb-ri (JAXB)

The tools for JAX-WS and JAXB are also available as Maven artifacts:

  • wsgen and wsimport: com.sun.xml.ws : jaxws-tools, plus tool scripts
  • schemagen and xjc: com.sun.xml.bind : jaxb-jxc and com.sun.xml.bind : jaxb-xjc, plus tool scripts

There are also Maven artifacts that contain just the APIs of the Java EE technologies:

  • javax.xml.ws : jaxws-api (JAX-WS, plus javax.xml.soap : javax.xml.soap-api for SAAJ and javax.xml : webservices-api for Web Services Metadata)
  • javax.xml.bind : jaxb-api (JAXB)
  • javax.activation : javax.activation-api (JAF)
  • javax.annotation : javax.annotation-api (Common Annotations)

Adding either the API JARs or the reference implementations to your class path together with all other javax.annotation-related JARs will work because all class path content ends up in the same module (the unnamed one) and thus split packages are no problem there.

Nicolai Parlog
  • 47,972
  • 24
  • 125
  • 255
  • 1
    Well for the same reasons, as mentioned by the OP to refrain from using `--patch-modules` and at the same time looking for [testing the entire application with a go-ahead](https://stackoverflow.com/questions/47258757/avoid-loading-a-transitively-dependent-module#comment81468419_47258757)... I found the [question unclear](https://stackoverflow.com/questions/47258757/avoid-loading-a-transitively-dependent-module#comment81468967_47258757) – Naman Nov 13 '17 at 11:01
  • @Nicolai: Thanks. I was exporting `javax.xml.soap` package from `java.xml.ws` module. To remove `java.xml.ws` from `--add-exports`, I would try using `javax.xml.soap-api` dependency to fix split package issue. – keenUser Nov 13 '17 at 11:52