我正在尝试使用JDK9的新AOT功能编译应用程序服务器,并且面临着许多挑战.
应用程序服务器包含~180 MB的罐子; 编译一起溢出整数,所以我试图将每个模块编译成一个(.so)库.这些模块与其他模块有依赖关系,所以我不得不使用-J-cp -J依赖项将它们放在classpath上.这导致了4.4 GB的libs - 因为AOT应该加速服务器启动,你可以想象从磁盘加载它并没有真正帮助.(可以剥离那些调试信息的库,但我们仍然在讨论与罐子相比规模增长的顺序.)
我很沮丧,jaotc实际上类加载编译的类,它触发静态构造函数(这有时会给我错误).此外,编译器无法处理缺少的引用类,有时这只是一个运行时依赖 - 即使没有它们,服务器也可以正常运行.所以我必须提供空的模拟类来满足编译器.
但是,当使用AOT跟踪(-Xlog:aot+class+load=trace:file=/tmp/aot.txt:none而不是stdout -XX:+PrintAOT)运行服务器时,我发现libs也包含一些依赖项:
found java.lang.Object in /home/user/aot/common/libjava.base-coop.so for classloader 0x2b5745e6ac80 tid=0x00002b574401e800
found java.lang.Object in /home/user/aot/appserver/lib/libcom.example.module1.so for classloader 0x2b5745e6ac80 tid=0x00002b574401e800
found java.lang.Object in /home/user/aot/appserver/lib/libcom.example.module2.so for classloader 0x2b5745e6ac80 tid=0x00002b574401e800
Run Code Online (Sandbox Code Playgroud)
这证实了我的疑问,lib只包含了我给编译器编译的jar中的代码,但至少包含了超类的代码.我也不确定JVM在多个库中找到相同类时的行为.
剥离重复是否可能?大/多库项目的推荐方法是什么?
JLS - Java语言规范 - https://docs.oracle.com/javase/specs/jls/se9/html/index.html
JSR - Java规范请求 - https://jcp.org/aboutJava/communityprocess/final/jsr376/index.html(模块系统)正式文档,描述了用于添加到Java平台的建议规范和技术.
JEP - JDK增强提案- http://openjdk.java.net/jeps/0,http://openjdk.java.net/jeps/261(模块系统)
这三者有什么区别?
概括
孵化器模块是将非最终 API 和非最终工具交到开发人员手中的一种方法,而 API/工具则在未来版本中朝着最终确定或删除的方向发展。
目标
使 JDK 发布项目能够分发一组有限的 API 和工具(网站上可能缺少“是”),这些 API 和工具不是最终的和完整的,并且可以从开发人员或用户的反馈中受益。这将减少 Java SE 平台和 JDK 中出现代价高昂的错误的机会。
概括
预览功能是 Java 语言、Java 虚拟机或 Java SE API 的一项新功能,它是完全指定、完全实现的,但不是永久的。它在 JDK 功能版本中可用,以激发开发人员根据实际使用情况提供反馈;这可能会导致它在未来的 Java SE 平台中永久存在。
目标
允许 Java 平台开发人员传达新功能是否会在未来 12 个月内以其当前形式“来到 Java”。
我想知道分别拥有这两个在概念上(甚至在语义上)非常相似的方面有什么意义?
是的,JEP 12 有更多的目标,定义和总结略有不同;而且它似乎与 JVM 内部有更密切的联系;然而,这两个 JEP 对我来说似乎很重叠。
有任何想法吗?
我正在尝试在运行时编译和加载动态生成的 Java 代码。由于 ClassLoader::defineClass 和 Unsafe::defineAnonymousClass 在这种情况下都有严重的缺点,因此我尝试通过Lookup::defineHiddenClass使用隐藏类。这对于我尝试加载的所有类都适用,但调用 lambda 表达式或包含匿名类的类除外。
调用 lambda 表达式会引发以下异常:
Exception in thread "main" java.lang.NoClassDefFoundError: tests/HiddenClassLambdaTest$LambdaRunner/0x0000000800c04400
at tests.HiddenClassLambdaTest.main(HiddenClassLambdaTest.java:22)
Caused by: java.lang.ClassNotFoundException: tests.HiddenClassLambdaTest$LambdaRunner.0x0000000800c04400
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:636)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:182)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:519)
... 1 more
Run Code Online (Sandbox Code Playgroud)
执行实例化匿名类的代码会引发以下错误:
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
tests/HiddenClassLambdaTest$LambdaRunner+0x0000000800c00400.run()V @5: invokespecial
Reason:
Type 'tests/HiddenClassLambdaTest$LambdaRunner+0x0000000800c00400' (current frame, stack[2]) is not assignable to 'tests/HiddenClassLambdaTest$LambdaRunner'
Current Frame:
bci: @5
flags: { }
locals: { 'tests/HiddenClassLambdaTest$LambdaRunner+0x0000000800c00400' }
stack: { uninitialized 0, uninitialized …Run Code Online (Sandbox Code Playgroud) 我最近一直在读巴拿马项目.
我知道它将成为JNI的下一代替代品 - 它将允许Java开发人员使用Java在本机层上进行编码(这是令人惊叹的恕我直言).
从我所看到的jnr-posix看,用法很简单,例如:
public class FileTest {
private static POSIX posix;
@BeforeClass
public static void setUpClass() throws Exception {
posix = POSIXFactory.getPOSIX(new DummyPOSIXHandler(), true);
}
@Test
public void utimesTest() throws Throwable {
// FIXME: On Windows this is working but providing wrong numbers and therefore getting wrong results.
if (!Platform.IS_WINDOWS) {
File f = File.createTempFile("utimes", null);
int rval = posix.utimes(f.getAbsolutePath(), new long[]{800, 200}, new long[]{900, 300});
assertEquals("utimes did not return 0", 0, rval);
FileStat …Run Code Online (Sandbox Code Playgroud) 我正在学习 Java 17,通过 JEP334(JVM Constants API),我知道如何获取ClassDesc, MethodTypeDesc, MethodHandleDesc, DynamicConstantDesc.
但这些物体能做什么呢?
在什么应用场景下需要这些对象?