为什么java 9模块系统具有java.se模块,该模块对其他模块具有传递依赖性.在Java 9之前的世界中依赖于整个rt.jar是不一样的.
module java.se {
requires transitive java.desktop;
requires transitive java.security.jgss;
requires transitive java.security.sasl;
requires transitive java.management;
requires transitive java.logging;
requires transitive java.datatransfer;
requires transitive java.sql.rowset;
requires transitive java.compiler;
requires transitive java.sql;
requires transitive java.naming;
requires transitive java.prefs;
requires transitive java.rmi;
requires transitive java.xml.crypto;
requires transitive java.management.rmi;
requires transitive java.xml;
requires transitive java.scripting;
requires transitive java.instrument;
}
Run Code Online (Sandbox Code Playgroud) 使用immutables-library可以正常使用java 9,直到我添加一个module-info.java项目,Immutables*.java将不再生成.
对于模块信息,我按照IntelliJ的建议添加"需要值".
我缺少什么,是一个immutables-library问题或我需要设置的其他东西,以便javac找到注释处理.
我正在使用maven-compiler-plugin:3.7.0配置为target/source = 9的 maven .
java maven java-platform-module-system java-9 immutables-library
我正在将 Java 桌面应用程序升级到 JDK10,并且需要利用模块来使用javapackager构建本机包。
一切都很好,直到我使用 Proguard (6.0.2) 添加了一个混淆步骤。一旦我启用了混淆(使用来自 < JDK9 项目的工作 proguard 配置文件),它就会按预期工作,但 Proguardmodule-info.class从输出 JAR 中删除了,这会阻止javapackager找到模块。
根据 Proguard 的injars参数文档
默认情况下,任何非类文件都将被复制而不做任何更改。
这里的问题是 module-info.class是一个“类”文件(尽管很奇怪)。“保留”规则取决于类名,所以我认为没有任何规则可以用来防止这种删除。
如何让 Proguard 保留module-info.class文件?
我正在将使用类路径的jar项目从Java 10迁移到使用Java 9拼图模块的Java 11。该项目有JUnit5测试。测试依赖项由maven在测试范围内提供。当另一个项目使用该模块时,如何使所有程序包打开以进行测试,但不打开?
jar项目只是为其他项目提供了一些类(例如实用程序项目)(因此不需要主类)。
该项目在/ src / main / java / a / b / c /中有5个软件包。使用此jar的项目应该可以访问其中的2个。其他3个仅供内部使用(供可访问者使用)。测试位于/ src / test / java / a / b / c /。这些测试具有测试范围中提供的依赖项(JUnit,mockito,junt-params),因为这些测试与使用此jar的项目无关
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我在/ src / main / java /中提供了一个module-info.java:
module moduleName {
requires java.base;
exports a.b.c.package1;
exports a.b.c.package3;
}
Run Code Online (Sandbox Code Playgroud)
因此,现在,第1包和第3包中的公共课程应该可以按预期供其他项目使用(我尚未能够对此进行验证)。
现在运行测试会导致java.lang.reflect.InaccessibleObjectException:无法访问abcpackage1.collections.SomeTest():模块moduleName不会“打开abcpackage1”到未命名的模块@ 6a84a97d
当我打开包装(带有opens)时,一切运行顺利。但是现在所有程序包都已打开。我希望仅在测试期间才能访问包2、4和5,并且不应打开包1和3进行反射(因此只能导出)。
我想到了,因为maven告诉我未命名的模块 @ 6a84a97d,所以这可能是为测试而创建的模块。这使我尝试在/ src / test / java /中添加一个 …
我将 Java 14 与 Jetty 9.4 和 Weld-servlet-shaded-3.1 一起使用,但出现此异常:
Caused by: java.lang.reflect.InaccessibleObjectException:
Unable to make protected final java.lang.Class
java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int)
throws java.lang.ClassFormatError accessible: module java.base does
not "opens java.lang" to module weld.servlet.shaded.
Run Code Online (Sandbox Code Playgroud)
根据这里的回答:https : //stackoverflow.com/a/41265267/5057736我试着添加
--add-opens java.base/java.lang=ALL-UNNAMED
Run Code Online (Sandbox Code Playgroud)
和
--add-opens java.base/java.lang=weld.servlet.shaded
Run Code Online (Sandbox Code Playgroud)
但没有人帮忙。谁能说一下怎么修?
编辑 1
我发现这个问题出现在 Java 12,13,14 OpenJDK/Oracle 中。但是,如果我使用 Java 11 OpenJDK/Oralce 一切正常,我什至不添加任何--add-opens. 怎么解释?
编辑 2
我检查了Jetty pom和Weld pom,它们都具有相同的属性:
<compiler.source>1.8</compiler.source>
<compiler.target>1.8</compiler.target>
Run Code Online (Sandbox Code Playgroud)
编辑 3
Java 版本
$ java -version
openjdk version "14" 2020-03-17
OpenJDK Runtime …Run Code Online (Sandbox Code Playgroud) 我有一个modules文件夹,内容为
antlr-runtime-3.5.2.jar
antlr4-4.8-1.jar
antlr4-runtime-4.8-1.jar
byte-buddy-1.10.10.jar
classmate-1.5.1.jar
cxf-core-3.4.1.jar
dom4j-2.1.3.jar
FastInfoset-1.2.13.jar
gmbal-4.0.1.jar
ha-api-3.1.12.jar
hibernate-commons-annotations-5.1.0.Final.jar
hibernate-core-6.0.0.Alpha6.jar
icu4j-61.1.jar
istack-commons-runtime-3.0.5.jar
jakarta.activation-1.2.2.jar
jakarta.activation-api-1.2.2.jar
jakarta.annotation-api-1.3.5.jar
jakarta.jws-api-2.1.0.jar
jakarta.transaction-api-1.3.3.jar
jakarta.xml.bind-api-2.3.3.jar
jakarta.xml.soap-api-1.4.2.jar
jakarta.xml.ws-api-2.3.3.jar
jandex-2.1.3.Final.jar
javax.activation-api-1.2.0.jar
javax.json-1.0.4.jar
javax.persistence-api-2.2.jar
jaxb-impl-2.3.3.jar
jaxws-rt-2.3.3.jar
jboss-logging-3.3.2.Final.jar
jboss-rmi-api_1.0_spec-1.0.6.Final.jar
jboss-transaction-api_1.2_spec-1.1.1.Final.jar
log4j-api-2.14.0.jar
log4j-core-2.14.0.jar
log4j-slf4j-impl-2.14.0.jar
management-api-3.2.2.jar
mimepull-1.9.13.jar
org.abego.treelayout.core-1.0.3.jar
pfl-basic-4.1.0.jar
pfl-tf-4.1.0.jar
policy-2.7.10.jar
saaj-impl-1.5.2.jar
slf4j-api-1.7.25.jar
ST4-4.3.jar
stax-ex-1.7.8.jar
stax2-api-4.1.jar
streambuffer-1.5.9.jar
txw2-2.3.0.jar
woodstox-core-6.2.1.jar
xmlschema-core-2.2.5.jar
Run Code Online (Sandbox Code Playgroud)
执行命令后
jlink --module-path="[path_]\target\modules" --compress=2 --add-modules=java.persistence,java.activation,spring.context,spring.beans,org.apache.cxf.core,java.xml,java.xml.bind,slf4j.api --no-header-files --no-man-pages --verbose --output="C:\Users\test\out"
Run Code Online (Sandbox Code Playgroud)
我收到一条错误消息
Error: Two versions of module jakarta.activation found in [path_]\target\modules (jakarta.activation-api-1.2.2.jar and jakarta.activation-1.2.2.jar)
Run Code Online (Sandbox Code Playgroud)
奇怪的是,当我删除jakarta.activation-api-1.2.2.jar或jakarta.activation-1.2.2.jar
Java 然后开始抱怨 …
这个应用程序出了什么问题.我认为classpath jar和模块jar的混合是有效的.对于没有明确模块信息的所有罐子成为自动模块?当我删除我的module-info.java时,它可以工作.因为IDEA在这种情况下使用了类路径.
Java(TM)SE运行时环境(版本9 + 176)
IntelliJ IDEA 2017.1.4
module-info.java
module test {
requires spring.boot.autoconfigure;
requires spring.boot;
}
Run Code Online (Sandbox Code Playgroud)
App.java
package com.foo.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
Run Code Online (Sandbox Code Playgroud)
的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo.test</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.M2</version>
</parent>
<name>test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.9</maven.compiler.source>
<maven.compiler.target>1.9</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url> …Run Code Online (Sandbox Code Playgroud) 我了解Java平台模块系统(JPMS)对大型应用程序的好处,但有没有理由将小型库或应用程序转换为(单个)模块?如果是这样,Modular Jar Files是实现这一目标的最佳方法,还是首选的常规方法?
展望未来,模块化的v.类路径程序会有性能影响吗?
为了能够更好地判断移植到Java 9时的反射风险,我想知道只要引用可访问类型,浅层反射代替静态编译是否安全:
我的意思是,我可以随时更换
PublicType p = (PublicType)(Factory.instance());
p.publicMethod();
Run Code Online (Sandbox Code Playgroud)
(Factory.instance()返回类型在哪里Object,将Package.PublicType从未打开的模块返回API类型()的子类型.
同
Object p = Factory.instance();
Class<?> c = Class.forName("package.PublicType");
Method m = c.getMethod("publicMethod", (Class[])null);
// assert p instanceof package.PublicType
m.invoke(p, (Object[])null); // throws?
Run Code Online (Sandbox Code Playgroud)
这个问题的早期版本关于我同时解决的特定代码问题.
但是一般的问题也很有意思:在返回的对象具有正确的子类型但是在调用或MethodHandle解析时无法进行访问检查.
在Java 9中,您可以选择将源目录打包为模块,方法是添加一个module-info.java,它定义了它导出的包,以及它依赖的其他模块.
但是,一旦这样做,您必须在模块描述符中列出所有依赖项 - 并且依赖项必须本身都是模块.因此,通过扩展,如果您模块化单个源目录,则必须对公司范围内的每个源目录进行模块化.
此外,您无法在Java 8或更早版本中定义模块,这意味着除了模块化每个Java源目录之外,还必须将所有内容转换为Java 9.同时.
如果您在一个拥有大量代码的公司工作,这似乎是灾难性的,这些代码由许多不同的项目共享.
现在,我可以通过设置一堆编译器标志来解决这个问题,以避免定义模块,但这似乎是一个非常糟糕的解决方案.
我希望我错误地理解这一点?
java java-platform-module-system java-9 java-module module-info
java ×10
java-platform-module-system ×10
java-9 ×6
maven ×3
gradle ×1
java-14 ×1
java-module ×1
jetty ×1
junit5 ×1
module-info ×1
proguard ×1
reflection ×1
spring ×1
weld ×1