Java 避免加载可传递依赖的模块

Java 避免加载可传递依赖的模块,java,java-9,java-module,Java,Java 9,Java Module,我正在使用JDK 9.0.1编译我的遗留源代码,如下所示: javac --add-modules=java.base,java.xml.ws -cp lib\jsr305.jar;lib\javax.annotation-api-1.2.jar TestJava.java TestJava.java:3: error: cannot find symbol import javax.annotation.Nonnull; ^ symbol:

我正在使用JDK 9.0.1编译我的遗留源代码,如下所示:

javac --add-modules=java.base,java.xml.ws -cp lib\jsr305.jar;lib\javax.annotation-api-1.2.jar TestJava.java
TestJava.java:3: error: cannot find symbol
import javax.annotation.Nonnull;
                       ^
  symbol:   class Nonnull
  location: package javax.annotation
它给出了一个错误,因为
jsr305.jar
中定义的注释由于问题而不可见。错误如下:

javac --add-modules=java.base,java.xml.ws -cp lib\jsr305.jar;lib\javax.annotation-api-1.2.jar TestJava.java
TestJava.java:3: error: cannot find symbol
import javax.annotation.Nonnull;
                       ^
  symbol:   class Nonnull
  location: package javax.annotation
这里加载模块
java.xml.ws.annotation
,因为它是
java.xml.ws
所必需的。因此它忽略了
jsr305.jar
中的类型。我不想加载这个模块,而是从
javax.annotation-api-1.2.jar
中引用它的所有注释类型。我也不想做
--patch module
,因为它会在未来的版本中崩溃

如果我使用
--limitmodule=java.xml.ws.annotation
,它会给出相同的错误。如果我从
-addmodules
中删除
java.xml.ws
,它会成功编译,但我需要从中导出一些API,因此无法删除它。是否有任何方法可以加载模块
java.xml.ws
,但不能加载
java.xml.ws.annotation

编辑:我想我给出了一个java.xml.ws.annotation和jsr305.jar之间拆分的示例,这增加了一些混淆。虽然这是我的实际问题,但我更感兴趣的是知道——我是否可以避免加载一个可传递依赖的模块,比如加载
java.xml.ws
,而不加载
java.xml.ws.annotation
?根据我在JEP261中的理解,它说

--限制模块(,)*

其中,
是模块名称。此选项的效果是限制 可观测的模块与命名对象的传递闭包中的模块相比较 模块加上主模块(如有),再加上任何其他模块 通过--addmodules选项指定


那么,为什么
--limit module
不阻止
java.xml.ws.annotation
加载呢?

我知道没有办法阻止传递依赖的解析

短期修复 您应该能够使用
——补丁模块java.xml.ws=lib\jsr305.jar:lib\javax.annotation-api-1.2.jar
。我的意见是:如果您只是想让您的构建在Java9上运行,那么这是一个很好的选择。这是一个有点可疑,但仍然可以接受,如果你想在生产中使用它

如果您担心长期兼容性:

  • 我认为,
    ——补丁模块
    不会很快消失——你有这方面的来源吗
  • 我敢肯定java.xml.ws很快就会被删除——它已经不推荐被删除
在你的位置上,我更担心模块,而不是修补它

长期解决方案 因此,对于长期解决方案,您应该删除对java.xml.ws的依赖。有一个关于这个的部分(有很多我懒得复制的链接):

JAX-WS和JAXB的参考实现(RIs)是一个很好的起点,因为它们完全替代了JDK 9中的java.xml.WS和java.xml.bind模块。RIs作为Maven工件提供:(注意,它们必须部署在类路径上)

  • com.sun.xml.ws:jaxws-ri(JAX-ws,加上SAAJ和Web服务元数据)
  • com.sun.xml.bind:jaxb-ri(jaxb)
JAX-WS和JAXB的工具也可以作为Maven工件提供:

  • wsgen和wsimport:com.sun.xml.ws:jaxws工具,以及工具脚本
  • schemagen和xjc:com.sun.xml.bind:jaxbjxc和com.sun.xml.bind:jaxbxjc,以及工具脚本
还有一些Maven工件只包含Java EE技术的API:

  • javax.xml.ws:jaxws-api(JAX-ws,加上javax.xml.soap:javax.xml.soap-api for SAAJ和javax.xml:webservices-api for Web服务元数据)
  • javax.xml.bind:jaxbapi(jaxb)
  • javax.activation:javax.activation-api(JAF)
  • javax.annotation:javax.annotation-api(通用注释)

将API JAR或引用实现与所有其他
javax.annotation
相关的JAR一起添加到类路径中会起作用,因为所有类路径内容都位于同一个模块(未命名的模块)中,因此拆分包不会有问题。

如果我从
中删除java.xml.ws--添加模块
,它还需要什么API?如果这是暂时的,我建议朝着这个方向向前看,否则就完全转向你了。计划是删除所有不推荐的API,并转移到模块化代码库。但这需要相当长的时间,在此之前,我想在Java9上构建和测试整个应用程序(非常庞大!!)。目前正在寻找一个至少能通过编译错误的方法。我也不想这样做——补丁模块,因为它会在未来的版本中崩溃。我以为你在寻找一些可能是长期的东西。在这一点上,我真的不清楚你目前的目标是什么,以及你打算如何迁移到Java9?也许在上面的场景中显示所有代码都会受到什么影响可以帮助任何人进一步帮助您。例如,当您从问题中的编译命令中删除
--addmodules=java.base,java.xml.ws
时,什么会失败?无论如何,类路径依赖不应导致拆分包@Keenusert问题中的场景是没有希望的,因为javax.annotation.*类位于模块javax.xml.ws.annotation、jsr305.jar和javax.annotation-api-1.2.jar中。您正在使用web服务API吗?如果是这样的话,最简单的方法就是下载独立版本并部署在类路径上。有关此主题的链接和所有详细信息可在中找到:出于相同的原因,正如OP所述,避免使用
--补丁模块,同时查找。。。我找到了@Nicolai:谢谢。我从
java.xml.ws
模块导出
javax.xml.soap
包。要从
--addexports
中删除
java.xml.ws
,我将尝试使用
javax.xml。