标签: classloader

运行时代码生成和编译

假设我有这段代码,它使用一些输入(例如 URL 路径)来通过反射来确定要运行的方法:

// init
map.put("/users/*", "viewUser");
map.put("/users", "userIndex");

// later
String methodName = map.get(path);
Method m = Handler.class.getMethod(methodName, ...);
m.invoke(handler, ...);
Run Code Online (Sandbox Code Playgroud)

这使用反射,因此可以提高性能。可以这样做:

// init
map.put("/users/*", new Runnable() { public void run() { handler.viewUser(); } });
map.put("/users", new Runnable() { public void run() { handler.userIndex(); } });

// later
Runnable action = map.get(path);
action.run();
Run Code Online (Sandbox Code Playgroud)

但手动创建所有这些Runnable都有其自身的问题。我想知道,我可以在运行时生成它们吗?因此,我将拥有第一个示例中的输入映射,并动态创建第二个示例的映射。当然,生成它只是构建一个字符串的问题,但是编译和加载它呢?

注意:我知道性能提升很小,这是过早优化的完美例子。因此,这是一个学术问题,我对运行时生成和代码编译感兴趣。

java code-generation javac runtime-compilation classloader

5
推荐指数
1
解决办法
5770
查看次数

Java类加载可视化/分析工具

是否有任何工具可以连接到 jvm 并实时显示类如何加载到该 jvm 中?我想它会成为一个很棒的 jvisualvm 插件..但是没有找到这样的东西让我想知道这是否可行?我只找到了一些看似“晦涩”的工具的参考资料,这些工具与 weblogic 或 webspere 严格相关。

假设这样的工具是可能的,它是否与特定容器严格相关?

谢谢!

jvm classloader

5
推荐指数
1
解决办法
1747
查看次数

是否有其他方法可以使用 Class.forName() 加载类?

在我的库的代码中,我使用 JAXB 从 XML 文件加载类名,以便稍后使用Class.forName(). 一个虚构的例子来说明这一情况:

public void libraryMethod() throws Exception {
  List<String> classNames = loadClassNamesFromXML();

  for (String className : classNames) {
    Class.forName(className).newInstance().doThings();
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,一些用户使用 OSGi 来配置他们的应用程序,他们使用与使用我的 XML 结构配置的类不同的类加载器来加载我的库。这意味着加载可能会失败,因为找不到该类。

有没有更可靠的方法来加载此类?或者还有其他方法来配置这些实例吗?我愿意接受导致此结果的建议:

public void libraryMethod() throws Exception {
  // Spring does things like this:
  List<SomeType> instances = loadInstancesFromXML();

  for (SomeType instance : instances) {
    instance.doThings();
  }
}
Run Code Online (Sandbox Code Playgroud)

一些限制:

  • 从库的角度来看,这些实例的生命周期并不重要。如果他们有(用户)状态,我的图书馆不会注意到。
  • 我想让这个库中的事情保持简单,所以我想避免在配置框架(例如 spring)上创建外部依赖项。因此,我只对可以使用标准 JDK 6+ 发行版实现的解决方案感兴趣。
  • 我真的很想保留我的简单 XML 配置文件(对 XML 结构稍作修改就可以了)。

java osgi classloader

5
推荐指数
1
解决办法
5986
查看次数

java -verbose:class 显示 servlet 已加载,但仅在访问 servlet 时才会初始化静态内容

我想我在这里弄错了。

我有一个简单的servlet静态块,可以打印一些消息。据我了解,当 servlet 类首次加载到 jvm 中时,应该处理静态块。

我正在使用嵌入式jetty并使用 jvm 选项启动 jetty 服务器-verbose:class

我可以在输出中看到该类在Servlet我第一次访问此 servlet 并查看消息之前很久就已加载。

但据我了解,静态块应该在类加载后立即初始化。我这里哪里错了?

java servlets classloader

5
推荐指数
1
解决办法
3312
查看次数

“__JVM_DefineClass__”作为类加载器位置意味着什么?

我正在调试eclipse远程调试动态编译加载类时无法加载源代码的原因。我看到的论点-verbose:class是我的动态编译的类文件来自__JVM_DefineClass__. 我认为这意味着它们来自 JVM 堆空间本身,因为我让编译器将编译后的字节输出到“文件管理器”中,该文件管理器将编译后的字节缓存在内存中。

似乎调试时源代码可查看的唯一方法是,如果我在源代码查找路径中指定实际加载的类来自的位置...并且如果我指定该类所在的目录,则似乎不起作用正在编译类。我觉得如果我将编译的字节保存到磁盘,源加载可能会起作用。

那么,什么__JVM_DefineClass__意思呢?我的假设正确吗?

java eclipse jvm classloader

5
推荐指数
1
解决办法
3371
查看次数

密钥库未从 jar 中加载 JKS 文件

经过几个小时的斗争后,我开始感到非常沮丧。

我有一个 JKS 服务器文件,我想从 jar 中加载它。只要文件在 Jar 之外,使用 FileInputStream 就可以了,但是一旦我尝试将其更改为 getResourceAsStream,它就不会接受它,并说(没有这样的文件或目录)。

这就是项目的分发方式

ProjectFolder
-src
--package.name
---JKS File
---Class calling the resource retrieval and loading into the keystore
Run Code Online (Sandbox Code Playgroud)

我想我已经尝试了几乎所有我能想到的 this.getClass().getClassLoader().getResourceAsStream("jksFile.jks") 组合。

我提前为没有更具体地说明代码而道歉,但我实际上已经忘记了我尝试过什么和没有尝试过什么。

帮助!

提前致谢

java loading classloader

5
推荐指数
1
解决办法
1万
查看次数

Apache Spark:类加载器在 jar 中找不到 classDef

我正在 Apache Spark 中以本地模式运行一个作业,该作业会将其结果保存到 s3a 文件系统。由于 Hadoop 2.6 没有 s3a:// 实现(或 s3://、s3n://)。我打包了一个 uber jar,其中包含 hadoop-aws 2.6.0 的所有传递依赖项,并将其与我的主要工作的 jar 一起提交。

但是,当我使用以下简约代码对其进行测试时:

sc.parallelize(1 to 100).saveAsTextFile("s3a://***/test10/")
Run Code Online (Sandbox Code Playgroud)

编译器在第一次运行时给了我这个错误:

java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
    at com.amazonaws.auth.AWSCredentialsProviderChain.<clinit>(AWSCredentialsProviderChain.java:41)
    at org.apache.hadoop.fs.s3a.S3AFileSystem.initialize(S3AFileSystem.java:112)
    at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2596)
    at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:91)
    at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2630)
    at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2612)
    at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:370)
    at org.apache.hadoop.fs.Path.getFileSystem(Path.java:296)
    at org.apache.spark.SparkHadoopWriter$.createPathFromString(SparkHadoopWriter.scala:170)
    at org.apache.spark.rdd.PairRDDFunctions.saveAsHadoopFile(PairRDDFunctions.scala:953)
    at org.apache.spark.rdd.PairRDDFunctions.saveAsHadoopFile(PairRDDFunctions.scala:863)
    at org.apache.spark.rdd.RDD.saveAsTextFile(RDD.scala:1290)
Run Code Online (Sandbox Code Playgroud)

如果我尝试再次运行,则会出现以下错误:

java.lang.NoClassDefFoundError: Could not initialize class com.amazonaws.auth.AWSCredentialsProviderChain
    at org.apache.hadoop.fs.s3a.S3AFileSystem.initialize(S3AFileSystem.java:112)
    at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2596)
    at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:91)
    at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2630)
    at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2612)
    at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:370)
    at org.apache.hadoop.fs.Path.getFileSystem(Path.java:296)
    at org.apache.spark.SparkHadoopWriter$.createPathFromString(SparkHadoopWriter.scala:170)
    at org.apache.spark.rdd.PairRDDFunctions.saveAsHadoopFile(PairRDDFunctions.scala:953)
    at org.apache.spark.rdd.PairRDDFunctions.saveAsHadoopFile(PairRDDFunctions.scala:863)
    at org.apache.spark.rdd.RDD.saveAsTextFile(RDD.scala:1290)
Run Code Online (Sandbox Code Playgroud)

奇怪的是:LogFactory …

java scala classloader apache-spark

5
推荐指数
1
解决办法
3107
查看次数

禁用类证书信息检查 (Java)

我创建了一个库,它将 jar 直接加载到当前类路径中以启动其类之一。但注入的 jar 包含证书,所以我收到此错误:

java.lang.SecurityException: class "TestClass" signer information does not match signer information of other classes in the same package
Run Code Online (Sandbox Code Playgroud)

这很正常,但我无法摆脱它。这是正常的,因为两个不同的 jar 正在“冲突”,但是,我无法删除 JAR 的证书,因为它是第三方的。

那么,我可以禁用类证书检查吗?或者做一些事情来消除这个错误?

我想我需要覆盖该ClassLoader.checkCerts方法......但这很脏......

java jvm classloader

5
推荐指数
1
解决办法
800
查看次数

覆盖系统类加载器

在 Java 中,可以使用以下方法替换默认系统 ClassLoader:

java -Djava.system.class.loader=com.test.MyClassLoader xxx
Run Code Online (Sandbox Code Playgroud)

这样,自定义类加载器用于加载新类,同时将默认系统类加载器作为其父类。

可以使用非运行时方法在 Android 应用程序中完成相同的系统 ClassLoader 替换吗?(gradle/manifest 或其他一些编译标志)

我不想在运行时替换系统类加载器,而是在整个应用程序启动时为整个应用程序设置一个不同的系统类加载器,甚至在应用程序类加载之前。

最终目标是在<clinit>调用Application 类之前运行代码(这基本上允许我按照我认为合适的方式加载应用程序中的所有类)。

android system classloader

5
推荐指数
0
解决办法
473
查看次数

Spring boot runnable jar 找不到通过 java.system.class.loader jvm 参数设置的类加载器

在这样的模块结构中:

项目
|
|- 通用模块
|- 应用模块

在 app 模块具有公共模块作为依赖项的情况下,我在公共模块中定义了一个自定义类加载器类。app 模块有一个-Djava.system.class.loader=org.project.common.CustomClassLoaderjvm 参数集来使用公共模块中定义的自定义类加载器。

在 IDEA 中运行一个 spring boot 项目,这非常有效。找到自定义类加载器,设置为系统类加载器,一切正常。

编译一个可运行的 jar(使用没有任何自定义属性的默认 spring-boot-maven-plugin),jar 本身包含所有类,并且在它的 lib 目录中是具有自定义类加载器的公共 jar。但是运行 jar 的-Djava.system.class.loader=org.project.common.CustomClassLoader结果是以下异常

java.lang.Error: org.project.common.CustomClassLoader
    at java.lang.ClassLoader.initSystemClassLoader(java.base@12.0.2/ClassLoader.java:1989)
    at java.lang.System.initPhase3(java.base@12.0.2/System.java:2132)
Caused by: java.lang.ClassNotFoundException: org.project.common.CustomClassLoader
    at jdk.internal.loader.BuiltinClassLoader.loadClass(java.base@12.0.2/BuiltinClassLoader.java:583)
    at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(java.base@12.0.2/ClassLoaders.java:178)
    at java.lang.ClassLoader.loadClass(java.base@12.0.2/ClassLoader.java:521)
    at java.lang.Class.forName0(java.base@12.0.2/Native Method)
    at java.lang.Class.forName(java.base@12.0.2/Class.java:415)
    at java.lang.ClassLoader.initSystemClassLoader(java.base@12.0.2/ClassLoader.java:1975)
    at java.lang.System.initPhase3(java.base@12.0.2/System.java:2132)

Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况?是因为在可运行的 jar 中,类加载器类位于 lib 目录中的 jar 中,因此类加载器试图在将 lib 类添加到类路径之前进行设置?除了将类加载器从 common 移动到所有其他需要它的模块之外,我还能做些什么吗?

编辑:我尝试将自定义类加载器类从通用模块移动到应用程序,但我仍然遇到相同的错误。这里发生了什么?

java spring classloader spring-boot

5
推荐指数
1
解决办法
969
查看次数