我正在尝试使用适合 Java 9 模块系统的最佳实践,这样我就可以减少工作量来获得好处(我们的系统现在真的可以从一些模块化中受益)。
在当前标准下,模块 A 导出包 com.example.foo 和模块 B 导出包 com.example.foo 是否允许?
作为一个相关的问题,如果相关的话,是这一点是否真正得到解决,或者它是否仍然不是最终的。
我碰巧知道,在下面的表达式中,使用i++将导致无限流,i将始终为 0。我感到困惑是因为我认为i++没有使用返回值,即使如此,它也不应该在i之后中断增量。
IntStream.iterate(0, i-> i<10, i-> ++i).forEach(....)
Run Code Online (Sandbox Code Playgroud) 我已经阅读了jshell 指南的介绍,但在 jshell 中找不到关于 -C 选项的描述/示例。
$jshell --help
-C<flag> Pass <flag> to the compiler.
Use one -C for each compiler flag or flag argument
Run Code Online (Sandbox Code Playgroud) 我有一个基于opendjdk:8-slim已安装 Tomcat 9的 Docker 容器,我正在调试从我的 IDE (IntelliJ) 部署在那里的应用程序 - IDE 在 Docker 主机上运行。我使用以下配置运行Tomcat
CATALINA_OPTS="-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=49520 \
-Dcom.sun.management.jmxremote.rmi.port=49520 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.local.only=false \
-Djava.rmi.server.hostname=10.0.75.1 \
-agentlib:jdwp=transport=dt_socket,address=49540,suspend=n,server=y"
Run Code Online (Sandbox Code Playgroud)
一切正常 - 我可以将 IDE 附加到容器。以下命令也有效(从 docker 主机执行) - 它可以连接到容器中的进程(容器中的端口 49540 映射到主机上的端口 49540):
docker-host$ telnet localhost 49540
Run Code Online (Sandbox Code Playgroud)
现在我想升级到 Java 9。我将基本映像从 更改openjdk:8-slim为openjdk:9-slim,但无法从 docker 主机连接到调试器端口。同样来自 IDE,我得到了SocketTimeoutException: Connection reset. 但是,从容器内部,我可以通过telnet.
我从openjdk存储库和其他存储库中尝试了几个 Java 9 图像,例如adenix/java,但不幸的是结果相同。
我正在为 Java 9 开发一个使用模块分层的启动器库。为了在层中添加模块,我需要将模块名称(作为字符串)传递给父级的配置。ModuleLayerJavadoc 在类文档的末尾有一个示例。
现在,我不想让我的库的用户承担声明模块名称的责任,而是允许只将 jar 文件位置作为String, URL, File, 或JarFile.
所以我的问题是,JarFile以编程方式提取模块名称的最简单方法是什么;自动的还是声明的?
我尝试使用 Gradle 在 Java 9 中开发一个小例子。但我没有找到制作工作运行配置的确切选项。我试图从这个小教程中复制正确的部分。但是 run 任务只是得到一个错误
java.lang.module.FindException:未找到模块 de.project.crawler
显然,我给 Gradle 的模块路径有误,但我不知道如何解决这个问题。
我的工作目录
project/
crawler/
| src/
| | main/
| | | java/
| | | | de.project.crawler/
| | | | | Main.java
| | module-info.java
| build.gradle
| settings.gradle
build.gradle
settings.gradle
Run Code Online (Sandbox Code Playgroud)
构建.gradle:
subprojects {
afterEvaluate {
compileJava {
inputs.property("moduleName", moduleName)
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
]
classpath = files()
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
爬虫/build.gradle:
plugins {
id 'java-library'
id 'application'
}
ext.moduleName …Run Code Online (Sandbox Code Playgroud) 我正在研究一个问题,以便在彼此之间存储两个类的引用
例如:
class A {
B b;
A(B b){
this.b = b;}
}
class B {
A a;
B(A a){
this.a = a;}
}
public static void main(String...s){
A a = new A(new B(null));
a.b.a = a;
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我使用以下语句而不是上面的初始化:
A a = new A(new B(a));
Run Code Online (Sandbox Code Playgroud)
我得到了以下错误,这很明显:
Main.java:19: error: variable a might not have been initialised
A a = new A(new B(a));
Run Code Online (Sandbox Code Playgroud)
但是如果我在JShell上尝试相同,它就可以正常工作(只是为了确保variable a从未初始化过,我variable a在执行语句之前检查过,确认它之前没有初始化:
可能是我在这里遗漏了一些东西,但有些人可以帮助我理解为什么在JAVA中执行同一语句有两种不同的行为.
理解这个问题的一个简单方法是允许使用以下语句,Jshell但不允许在正常程序中:
var somevar = somevar;
Run Code Online (Sandbox Code Playgroud) 在大多数编程语言中,开发人员有责任编写不可变的单例类等。
但是,我觉得这是重复的样板代码。更新的编程语言为实现此目的提供了更好的支持。
Java 9是否引入了任何注释或类似构造来将类标记为不可变或单例?
我在JDK 9上使用Ignite遇到麻烦。我有以下最小测试用例:
package no.ovstetun.ignite;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.junit.Test;
public class FailingIgniteTest {
@Test
public void failingIgnite() {
TcpDiscoverySpi discoverySpi = new TcpDiscoverySpi();
}
}
Run Code Online (Sandbox Code Playgroud)
此代码示例失败,并带有以下stacktrace:
java.lang.ExceptionInInitializerError
at org.apache.ignite.internal.util.IgniteUtils.<clinit>(IgniteUtils.java:769)
at org.apache.ignite.spi.IgniteSpiAdapter.<init>(IgniteSpiAdapter.java:119)
at org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi.<init>(TcpDiscoverySpi.java:231)
at no.nrk.mdb.common.infrastructure.ignite.IgniteConfigurationTest.failingIgnite(IgniteConfigurationTest.java:10)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused …Run Code Online (Sandbox Code Playgroud) 是否可以告诉eclipse添加以下命令行选项:
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
编译时.
我认为在运行测试时也可能需要它.
请注意,我尝试将这些添加到我的一个单元测试的VM选项中,但这不起作用.