由于Jigsaw项目的核心是Java模块系统,因此能够仅限制对特定模块内特定程序元素(类,方法和字段)的访问是很好的.
当模块中的某些元素对于此模块基本上是公共的时,它可能会有所帮助,但不应在此模块外部访问.
所以我说的是"package-local"之后的下一级访问,可以命名为"module-local".
然而,简要介绍Jigsaw规则和早期规范并没有帮助我弄清楚这种功能.更具体地说,该Modifier规范不包含任何新元素.
那么在未来的Java 9中还有其他任何可能吗?
我有以下Java 9模块:
module com.example.a {
exports com.example.a;
}
Run Code Online (Sandbox Code Playgroud)
使用导出类型:
public class Api {
public static void foo(ImplDetail args) {}
}
Run Code Online (Sandbox Code Playgroud)
和非导出类型:
package com.example.b.internal;
public class ImplDetail {}
Run Code Online (Sandbox Code Playgroud)
导出的类型使用非导出类型作为公共方法中的方法参数类型.我假设编译器会拒绝这种不一致的类配置,因为其他模块中的客户端无法真正调用该foo()方法,因为它们无法实例化参数类型.
令我惊讶的是,这个模块是由javac成功编译的.我可以看到传递的特殊情况null,但我仍然认为这样的API定义格式错误,并且认为它不应该被支持,理想情况下由编译器强制执行.
不解除这种情况的原因是什么?
我正在尝试构建一个针对Java 9 的开源项目.我需要使用反射访问一些文件,但我不能,因为它们的模块不会导出包.我使用参数将包导出到未命名的模块--add-exports.
我在环境变量中添加了以下参数_JAVA_OPTIONS:
-Dsun.reflect.debugModuleAccessChecks=true
--add-exports=javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED
--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED
Run Code Online (Sandbox Code Playgroud)
我正在使用最新的JDK 9版本(截至今天):
C:\controlsfx>java -version
java version "9"
Java(TM) SE Runtime Environment (build 9+175)
Java HotSpot(TM) 64-Bit Server VM (build 9+175, mixed mode)
Run Code Online (Sandbox Code Playgroud)
这是我尝试构建项目时的输出:
C:\controlsfx>.\gradlew :controlsfx:build
Picked up _JAVA_OPTIONS: -Dsun.reflect.debugModuleAccessChecks=true --add-exports=javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED --add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
:controlsfx:compileJava
C:\controlsfx\controlsfx\src\main\java\impl\org\controlsfx\behavior\SnapshotViewBehavior.java:60: error: package com.sun.javafx.scene.control.behavior is not visible
import com.sun.javafx.scene.control.behavior.BehaviorBase;
^ …Run Code Online (Sandbox Code Playgroud) 我在这里关注Jigsaw 快速入门.我成功运行了jlink给出的命令:
jlink --module-path $JAVA_HOME/jmods:mlib --add-modules com.greetings --output greetingsapp
Run Code Online (Sandbox Code Playgroud)
这会生成一个"运行时映像",它是一个展开的目录结构,如下所示:
~ tree -d greetingsapp
greetingsapp
??? bin
??? conf
? ??? security
? ??? policy
? ??? limited
? ??? unlimited
??? include
? ??? darwin
??? legal
? ??? java.base
??? lib
??? jli
??? security
??? server
Run Code Online (Sandbox Code Playgroud)
我该怎么办?我期待一个二进制可执行文件,而不是一个展开的目录树.
该bin目录有一个java和一个keytool.我没有看到任何.jar文件或.class文件通过捆绑的java可执行文件运行.
我有一些java9模块使用的第三方库不是Java9模块,只是一个简单的实用工具jar.
但是,编译器抱怨它无法从我的实用程序中找到包.
我应该怎么做module-info.java才能使用我的第三方库?
我正在关注IntelliJ IDEA 2018.2.5 中的Project Jigsaw:Module System Quick-Start Guide。我在 IDE 中做的一切都是正确的,直到链接器部分。有没有办法在 IntelliJ IDEA 中使用 jlink?
jlink(参见JEP 282)是链接器工具,可用于链接一组模块及其传递依赖,以创建自定义的模块化运行时映像(参见JEP 220)。
- Project Jigsaw:模块系统快速入门指南
我在JetBrains Bug & Issue Tracker 中发现了这个能够产生 JLink 人工制品的问题,但它已经开放了 2 年多,甚至没有描述。
作为一种解决方法,我已经看到了这个是否有 maven jigsaw jlink 插件?有趣的问题和最有前途的替代品似乎是Apache Maven JLink Plugin,但它也已经存在 2 年多了,但尚未发布。
我有一个简单的Java 9 SE项目,其中一个依赖于非模块化项目(在本例中选择了Weld SE),我正在尝试使用Maven(clean install)构建它.为了使Java 9能够启动,我已经添加了module-info.java.最初,此文件仅包含模块名称,并且没有requires公式.
请记住,我唯一的依赖是不是一个模块化的项目,因此,我认为Maven会放在类路径中(不模块路径),因此它会在结束unnamed module中描述的模块化系统的状态.
现在,我的Maven版本是3.3.9,我知道我需要在版本3.6中使用Maven编译器插件,如此处所述当然我已经使用jigsaw下载了JDK 9 EA build并设置了Maven来使用它.
如果我没有构建我的项目module-info.java,一切正常,将东西添加到类路径并构建成功.我想只要你遗漏那个文件,Maven就会坚持旧的方式.
但是,建造它有 module-info.java告诉我,从我的依赖的类不能在类路径中找到.所以我在调试模式下运行Maven(使用-X),确实 - 所有jar都在module-path下,classpath为空.这实际上意味着我的所有依赖项都被转移到自动模块中,我需要声明它们module-info.java.
一旦我声明了自动模块要求(链接到项目的module-info),我就可以在JDK 9上构建它.但它有点混乱 - 我唯一的pom.xml依赖是weld-se-core,但我module-info要求我宣布更多的编译要求通过.
这是一个完整的GitHub项目,可以观察到所有这些.
所以我的问题是:
automatic module并且需要声明它们?automatic module,我可以告诉Maven以某种方式过渡性地允许我的依赖需要引入的任何东西吗?例如Weld的其他部分,CDI API等.requires模块,我不直接使用?例如weld.environment.common我正在尝试使用Java 9 Jigsaw模块系统(还没有模块经验),并希望用它来封装我项目中的类,但这很令人困惑.
根据这篇文章,应该可以在一个项目中拥有多个模块.我在Eclipse Oxygen(支持Java 9)中创建了一个新项目,其结构与本文中所示的相同.但Eclipse一直告诉我,我不能module-info.java在一个项目中拥有多个.
我真的不知道如何告诉Eclipse它应该使用"多模块模式".我真的很感激不必为每个模块创建一个新项目.
这有效:
这不是:
如何使用Eclipse部署模块化项目?关于新的jmod扩展没什么可看的.我仍然像以前一样将其导出为可运行的JAR文件吗?
请注意,我的问题涉及使用IDE(没有命令行,我的意思是IDE应该是可能的,对吗?)谢谢你启发我.
我花了一些时间将我用Groovy编写的项目迁移到Java 10.现在可以编译并运行它.但它仍然没有使用Java 9模块化的任何好处.
谷歌搜索Groovy和Java 9模块几乎没有.
那么是否可以迁移Groovy项目以使用带有Project Jigsaw模块的JDK 10?
我创建了两个小项目de.app1和de.app2,其中App从de.app1使用Test从de.app2.
??? de.app1
? ??? de
? ? ??? app
? ? ??? App.java
? ??? module-info.java
??? de.app2
??? de
??? test
??? Test.java
Run Code Online (Sandbox Code Playgroud)
第一个项目中的module-info.java只包含module de.app1 {}
我编译了第二个项目并创建了一个jar文件:
javac de/test/Test.java
jar cf app2.jar de/test/Test.class
Run Code Online (Sandbox Code Playgroud)
然后尝试编译第一个项目,如下所示:
javac -cp ../de.app2/app2.jar de/app/App.java module-info.java
Run Code Online (Sandbox Code Playgroud)
失败,因为Test无法找到.当我在没有module-info.java的情况下编译项目时,一切正常.
是否有可能在Java 9模块中使用不是Java 9模块的jar中的类?特别是对于依赖第三方项目的项目(例如apache-commons,......),我认为需要这样的东西.
java-platform-module-system ×10
java ×9
java-9 ×9
jlink ×2
maven ×2
eclipse ×1
groovy ×1
java-module ×1
modularity ×1
module ×1
project ×1