各种资源(infoq,jigsaw-dev,osdir)表明LayerInstantiationException,即使包是模块的内部(未导出),在不同的java模块中具有相同的包也将导致a .
这似乎与要求所说的完全相反:
Java编译器,虚拟机和运行时系统必须确保包含相同名称的包的模块不会相互干扰.如果两个不同的模块包含相同名称的包,那么从每个模块的角度来看,该包中的所有类型和成员仅由该模块定义.
那么(将)应用程序使用的两个模块能够包含同名的私有包吗?
编辑
这是Stanislav Lukyanov指出的JMPS 问题
如何在Java 9中按类获取模块名称?例如,让我们考虑以下情况.有两个命名模块 - ModuleA和ModuleB.ModuleA对ModuleB一无所知.ModuleB需要ModuleA.
ModuleA包含类:
public class ClassA {
public void printModuleName(Class klass) {
//how to get here name of the module that contains klass?
}
}
Run Code Online (Sandbox Code Playgroud)
ModuleB包含类:
public class ClassB {
public void doIt() {
ClassA objectA = new ClassA();
objectA.printModuleName(ClassB.class);
}
}
Run Code Online (Sandbox Code Playgroud)
怎么做?
假设我正在开发一个由2个模块组成的模块化应用程序:com.spacey.explorer这取决于com.spacey.rocket模块.我在某些bin目录中有他们的模块化JAR文件.
我想准备轻量级JRE来运行它.显然,我使用jlink工具:
$ jlink --module-path /opt/jdk-9/jmods:../bin --add-modules com.spacey.explorer --output ~/custom-jre3
Run Code Online (Sandbox Code Playgroud)
现在,当我在JRE中列出模块时,我得到以下内容:
$ java --list-modules
com.spacey.explorer
com.spacey.rocket
java.base@9
Run Code Online (Sandbox Code Playgroud)
也就是说,我的应用程序模块捆绑到JRE中.但是如果我想构建一个只有JDK源模块的JRE,这些模块足以运行我的应用程序并保持我的应用程序模块分离,我必须知道我的JDK依赖项是什么(在这个例子中就是这样java.base)并明确指定它们喜欢:
$ jlink --module-path /opt/jdk-9/jmods --add-modules java.base --output ~/custom-jre3
Run Code Online (Sandbox Code Playgroud)
有没有办法让jlink为我这样做?或者任何可以为我找出那些JDK起源的依赖项的工具?
我有一个Java applet,它提供了一个GUI来调用Web服务.它使用Jaxb来解析XML数据并将其解组为对象.它使用Java 1.5到1.8正确运行.使用Java 9,不是那么多.
我使用容器HTML在Internet Explorer 8 + JDK 9中启动它:
<applet code="com.blah.MyApplet" archive="myFatJarWithDependencies.jar" mayscript>
<param name="cache_option" value="no" />
</applet>
Run Code Online (Sandbox Code Playgroud)
小程序加载很好,似乎工作; 但是,一旦我连接到Web服务,它那种停止工作.我把它缩小到这个代码片段(其中Foo是一个带有XML绑定注释的自动生成的类):
System.out.println("1");
JAXBContext jc = JAXBContext.newInstance(Foo.class);
System.out.println("2");
Run Code Online (Sandbox Code Playgroud)
Java的控制台显示1,然后......没有:它没有崩溃,applet仍然响应鼠标点击,它不会抛出任何异常......似乎根本没有错误.除了它没有对接收的数据做任何事情,它从不输出2.我已经尝试了替代JAXBContext.newInstance方法(使用包名,包名加上类加载器),但它们都是一样的.
如果我使用相同的JDK 9从Eclipse Oxygen运行项目,它确实有效.当我连接到Web服务时,它会输出一些警告,包括:
WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector
(file:/C:/.../.m2/repository/com/sun/xml/bind/jaxb-impl/2.0/jaxb-impl-2.0.jar) to method
java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int)
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access
operations
Run Code Online (Sandbox Code Playgroud)
但随后它继续并加载数据(并输出2到控制台).我的猜测是同样的问题,即使Java控制台中没有显示警告.也许JDK默认--illegal-access=deny是从IE运行的时候?或者"默默地否认 - 所以 - 用户 - 不要发生什么线索" …
我认为JPMS不支持模块版本.但是,当我这样做时,java --list-modules我有以下输出:
java.activation@9
java.base@9
java.compiler@9
java.corba@9
java.datatransfer@9
java.desktop@9
java.instrument@9
....
Run Code Online (Sandbox Code Playgroud)
所以,我无法理解这@9是什么.这个版本还是什么?如果JPMS支持模块版本,我可以在模块A的module-info中设置,模块A是否需要某个版本的模块B?
我想知道模块边界是否也是安全边界?
更具体地说,没有非法访问(--illegal-access=deny)和拒绝访问jdk.unsupported,它看起来accessClassInPackage不会再导致完整的沙箱逃脱.
真的吗?当此权限授予不受信任的代码时,是否还有其他方法可以破坏JVM的安全性?
要明确:
ReflectPermission("supressAccessChecks")- 未授予ReflectPermission("supressAccessChecks")您需要访问-Djava.security.manager模块和--illegal-access=deny- 未授予RuntimePermission("loadLibrary.*")通过反射访问sun.misc.Unsafe,RuntimePermission("accessClassInPackage.sun.misc")必须打开ClassLoader.defineClass您的模块 - 它不是.所以要么:
setAccessible(true)?我尝试将其maven-shade-plugin用于模块化jar:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<minimizeJar>true</minimizeJar>
<artifactSet>
<includes>
<include>javax.xml.bind:jaxb-api</include>
<include>com.sun.xml.bind:jaxb-impl</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>javax.xml.bind</pattern>
<shadedPattern>org.update4j.javax.xml.bind</shadedPattern>
</relocation>
<relocation>
<pattern>com.sun.xml.bind</pattern>
<shadedPattern>org.update4j.com.sun.xml.bind</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)
但是Maven会module-info.class从阴影罐中删除我,并发出警告:
[WARNING] Discovered module-info.class. Shading will break its strong encapsulation.
Run Code Online (Sandbox Code Playgroud)
我如何配置它离开它?
编辑:警告实际上是在删除阴影jar的模块描述符而不是我自己的模块描述符时发生的。
背景:
在我的组织中,有很多基于Java的Windows桌面应用程序。在我们专有的软件部署系统中,应用程序不包含单独的JRE / JDK。而是将通用的JRE(到目前为止,Oracle 8 Java SE JRE)部署到用户计算机,该计算机根据环境变量附加到各个应用程序。
我们希望将JRE从Oracle 8 Java SE JRE迁移到OpenJDK 11,而无需修改应用程序。从Java 8到Java 11删除了各种库,例如JavaFX。使用Java模块系统和jlink工具,我可以创建自己的专有JDK(通过OpenJFX增强):
jlink --module-path ..\mods;C:\Temp\javafx-jmods-11.0.2 --add-modules=ALL-MODULE-PATH,java.base,java.compiler,java.datatransfer,java.desktop,... --output C:\Temp\OpenJDK+OpenJFX
Run Code Online (Sandbox Code Playgroud)
需要JavaFX的应用程序可以使用此专有JDK,而无需进行更改。
当我尝试将相同的方法应用于最新的JAXB beta时,出现以下错误:
jlink --module-path ..\mods;C:\Temp\jaxb-ri-2.4.0-b180830.0438\jaxb-ri\mod --add-modules=java.xml.bind,java.base,java.compiler,java.datatransfer,java.desktop,java.instrument,... --output C:\Workspace\Java\OpenJDK_11.0.2_JFX_JAXB
Error: automatic module cannot be used with jlink: java.activation from file:///C:/Temp/jaxb-ri-2.4.0-b180830.0438/jaxb-ri/mod/javax.activation-api.jar
Run Code Online (Sandbox Code Playgroud)
根据https://github.com/eclipse-ee4j/jaf/issues/13,“ JAXB API使用Activation-api作为其依赖项,由于缺少module-info而被迫将其用作自动模块或从类路径中使用.java描述符文件。 ”
此外,是否可以在JDK 11上使用jlink来创建包含已删除的Java SE EE模块的运行时?我可以使用Java 10中的jlink捆绑模块java.xml.bind,该模块仍包含该模块。如果我将OpenJDK 10.0.2中的两个模块添加到模块路径,则jlink确实成功:
jlink --module-path ..\mods;C:\Temp\jdk-10.0.2\jmods\java.xml.bind.jmod;C:\Temp\jdk-10.0.2\jmods\java.activation.jmod --add-modules=java.xml.bind, ...
Run Code Online (Sandbox Code Playgroud)
但是,当我使用生成的JDK运行应用程序时,出现如下错误:
!ENTRY org.eclipse.osgi 4 0 2019-02-15 15:58:58.642
!MESSAGE Application error
!STACK 1
org.eclipse.e4.core.di.InjectionException: java.lang.NoClassDefFoundError: javax/annotation/PostConstruct
at …Run Code Online (Sandbox Code Playgroud) 我想创建hello world java 9应用程序,并以intellij的想法启动它。
内部模块-info.java的内容:
module my.module.Second {
requires my.module.First;
}
Run Code Online (Sandbox Code Playgroud)
外部模块-info.java的内容:
module my.module.First {
exports my.pack;
}
Run Code Online (Sandbox Code Playgroud)
但是idea抱怨我的项目:
Error:(1, 1) java: too many module declarations found
Run Code Online (Sandbox Code Playgroud)
我不明白为什么会这样以及真正的错误是什么。所以
我的问题是如何强迫思想接受我的世界。
PS 乍一看,错误似乎很明显,但是我有从github下载的具有相同结构的项目,但是它可以正常工作,并且想法没有抱怨:
java intellij-idea java-platform-module-system java-9 java-module
我试图了解使用 Java 平台模块系统 (JPMS) 构建项目与使用 multi-poms 构建项目之间的区别。
主要区别是 JPMS 封装代码而多 pom 项目分离项目依赖关系?
我在谷歌上搜索过,但没有找到对差异的很好解释,但我看到模块这个词可以互换使用。
java ×10
java-module ×10
java-9 ×7
jaxb ×2
maven ×2
applet ×1
java-11 ×1
java-platform-module-system ×1
jdeps ×1
jlink ×1
module ×1
module-info ×1
multi-module ×1
sandbox ×1
security ×1