【问题标题】:How to get name of jar from which class is loaded at runtime by JVM in Java 11java - 如何在Java 11中获取JVM在运行时加载的jar的名称
【发布时间】:2020-04-13 10:32:30
【问题描述】:

我使用了 JAVA_OPTS -Xlog:class+load=debug(在 Tomcat 9 startup.bat 中),虽然它显示了类名,但它显示源为 source: __JVMDefineClass__。有什么方法可以让我知道 Jar 的名称,就像它在 JAVA 8 中显示的那样?

例如

在 JAVA 8 中:[Loaded java.lang.Object from C:\Program Files\Java\jdk1.7.0_04\jre\lib\rt.jar],但是,

在 JAVA 11 中:com.fasterxml.jackson.databind.util.ClassUtil$Ctor source: __JVM_DefineClass__

更新:我正在使用 TomeePlus。

【问题讨论】:

  • 'JVM_DefineClass' 字符串是显示为所有其他类的来源还是仅显示为这个?
  • __JVM_DefineClass__ 显示用于除从 Tomcat 库加载的类之外的所有类。对于从 tomcat lib 文件夹加载的类,它会显示正确的 lib 名称和路径。
  • 我也看到Tomee的TempClassLoader加载的类有这样的源码,但是URLClassLoader加载的类有jar名。

标签: java classloader java-11 tomcat9 java-opts


【解决方案1】:

我已经使用 Spring Boot 的嵌入式 Tomcat 运行了一些测试,并且用作类源的 __JVM_DefineClass__ 字符串与 JVM 版本无关。它发生在我的测试期间的日志中,原因是:

  • 内部类,例如您提到的one,或
  • 动态生成的类,例如jdk.internal.reflect.GeneratedConstructorAccessor1

在我看来,这是由于源位置 URL 尚未对 ClassLoader 可用。你可以阅读下面负责定义__JVM_DefineClass__字符串的OpenJDK 11源代码的sn-p。

// common code for JVM_DefineClass() and JVM_DefineClassWithSource()
static jclass jvm_define_class_common(JNIEnv *env, const char *name,
                                  jobject loader, const jbyte *buf,
                                  jsize len, jobject pd, const char *source,
                                  TRAPS) {
  if (source == NULL)  source = "__JVM_DefineClass__";
  ...

OpenJDK / jdk / jdk11

【讨论】:

  • 某些类路径包含额外的“/”,导致它们的 URL 值无效。只是为了调试,我修改了 TempClassLoader,我认为这可能会解决我的问题。谢谢。
猜你喜欢
  • 2023-03-08
  • 2011-12-19
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
  • 2011-05-07
相关资源
最近更新 更多