- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在开发一个应用程序,我在自定义启动器中按以下方式直接将一些类注入(inject) JVM:
第 1 步:使用 LoadLibrary(C++ 代码)加载 jvm dll
第 2 步:实际注入(inject)类:(注意这使用引导类加载器)
jclass ljcl_LoadedClass = env->DefineClass(className, NULL, classBytes, classSize);
第 3 步:启动应用程序jniEnvironment_->CallStaticVoidMethod
实际调用 main 方法并启动应用程序。
稍后在 Java 代码中,我尝试使用注入(inject)的类
mySingleton = MySingletonClass.getInstance();
此行导致 NoClassDefFound 异常,我很难解决。请注意,相同的代码适用于 Java SE-7,因此这可能是由于对垃圾收集类的方式进行了一些更改或由于类加载器的可见性发生了变化 - 我只是停留在如何调试它并找到原因。
另一个有趣的事情是,在 C++ 代码中(在启动应用程序之前,但加载了 JVM dll,下面的代码实际上找到了类,我什至可以调用 getInstance 方法:
jclass olDecryptorClass = jniEnvironment_->FindClass("com/foo/bar/MySingletonClass");
最佳答案
我认识 Andrea 并找到了原因和解决方案,但不知道为什么 Java 8 会发生这种变化。
我在使用 Java 代理的原始问题中缺少关键信息,并且代理使用了导致 NoClassDefFoundError
的类。
我创建了一个非常简单的 C++ 控制台应用程序来启动 JVM,一个简单的 Agent,它在调用 premain()
方法时向控制台输出“Agent Started”,然后是“Loading class: className"通过我们重写的 ClassFileTransformer.transform()
方法。
使用 Java 7 时,我们在调试时得到以下信息:
C++ 步骤
options[1].optionString = "-javaagent:simple-agent.jar";
errorCode = createJavaVM(&javaVM, (void**)&jniEnv, &initArgs);
控制台
Agent Started
C++ 步骤
jclass ljcl_LoadedClass = jniEnv->DefineClass(CLASS_NAME, NULL, ljby_ClassBytes, lji_Size);
控制台
Loading class: com/foo/bar/JVMDefinedClass
C++ 步骤
jniEnv->CallStaticVoidMethod(helloWorldClass, mainMethod, mainArgs);
控制台
Loading class: com/for/bar/HelloWorld
Hello World!
在 Java 8 中,这变成了:
C++ 步骤
options[1].optionString = "-javaagent:simple-agent.jar";
errorCode = createJavaVM(&javaVM, (void**)&jniEnv, &initArgs);
控制台
Agent Started
Loading class: java/lang/invoke/MethodHandleImpl
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 4 more
Caused by: java.lang.ClassNotFoundException:
... 8 more
Loading class: java/lang/invoke/MethodHandleImpl$1
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 5 more
Loading class: java/lang/invoke/MethodHandleImpl$2
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 5 more
Loading class: java/util/function/Function
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 5 more
Loading class: java/lang/invoke/MethodHandleImpl$3
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 5 more
Loading class: java/lang/invoke/MethodHandleImpl$4
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 5 more
Loading class: java/lang/ClassValue
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 5 more
Loading class: java/lang/ClassValue$Entry
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 6 more
Loading class: java/lang/ClassValue$Identity
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 7 more
Loading class: java/lang/ClassValue$Version
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 7 more
Loading class: java/lang/invoke/MemberName$Factory
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 5 more
Loading class: java/lang/invoke/MethodHandleStatics
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 4 more
Loading class: java/lang/invoke/MethodHandleStatics$1
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 5 more
Loading class: sun/misc/PostVMInitHook
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
... 3 more
C++ 步骤
jclass ljcl_LoadedClass = jniEnv->DefineClass(CLASS_NAME, NULL, ljby_ClassBytes, lji_Size);
控制台
Loading class: com/foo/bar/JVMDefinedClass
C++ 步骤
jniEnv->CallStaticVoidMethod(helloWorldClass, mainMethod, mainArgs);
控制台
Loading class: com/objectiflune/simple/TestClass
java.lang.NoClassDefFoundError: com/foo/bar/JVMDefinedClass
at com.foo.bar.ClassTransformer.transform(ClassTransformer.java:41)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
... 13 more
Hello World!
很容易看出为什么最初的 14 个 java/lang
类找不到我们的 JVMDefinedClass,它还没有被定义。但即使在我们定义了它之后,似乎也会出现一些链式 react ,导致应用程序的其余部分找不到该类。
因此,解决方案是确保我们的 ClassFileTransformer.transform()
方法忽略这些(以及任何)Java 系统类:
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if (className.equals("com/foo/bar/JVMDefinedClass")
|| className.startsWith("com/sun")
|| className.startsWith("java/")
|| className.startsWith("javax/")
|| className.startsWith("org/ietf")
|| className.startsWith("org/jcp")
|| className.startsWith("org/omg")
|| className.startsWith("org/w3c")
|| className.startsWith("org/xml")
|| className.startsWith("sun/")
|| className.startsWith("com/oracle/")
|| className.startsWith("jdk/")
|| className.startsWith("oracle/")
|| className.startsWith("javafx/")
) return null;
//... rest of method ...//
现在我们不处理这 14 个类,没有 NoClassDefFoundError
被抛出,应用程序按预期运行。
我唯一不明白的是为什么 Java 8 中的 JVM 现在通过代理发送这 14 个类,而以前没有,以及这是否应该发生。
关于Java SE-8 使用 JNI DefineClass 注入(inject)类导致 NoClassDefFound,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30622474/
这个问题已经有答案了: NoClassDefFound when trying to run java with external libraries (4 个回答) 已关闭 8 年前。 如何从命令行
我在我的 Java 项目中使用 .dll(Eclipse IDE,如果有帮助的话),假设这个 .dll 包含类“myclass”并且我导入了它。构建时没有错误。 我在使用以下代码时遇到问题(NoCla
我正在尝试使用 netbeans 将我的 java 程序编译为单个 .jar 文件,并包含多个库。尝试使用以下命令通过 cmd 运行时,出现 NoClassDefFound 和 ClassNotFou
我遇到了编译器给我的这个错误: 线程“main”java.lang.NoClassDefFoundError中出现异常:javax/media/opengl/GLProfile 我的类路径中确实有 j
编辑:这个项目演示了行为: https://github.com/NathanielWaggoner/AndroidExamples/tree/master/packing 有一个读我解释了您第一次构
我不明白NoClassDefFoundError在 running an OpenEJB client 的背景下: thufir@doge:~$ thufir@doge:~$ java -classp
我已经被某个点困扰了几个小时,我正在初始化我从应用程序类调用的 Controller.java 类中的一些代码,它早些时候在所有设备上工作,但从昨天开始,我在 lolipop 以下的设备上收到 NoC
我有点被 xstream 的问题困住了。我有两个基于 OSGI 的 RCP 应用程序。他们使用 xstream 在 XML 文件中写入和读取某些类。当我运行程序并触发有问题的代码时,我得到: com.
我正在尝试将具有多个 jar 的小程序添加到 HTML 页面,但尝试在浏览器中运行该程序时出现 NoClassDefFounderror: db.DAO 。 DAO 是 TheaterApplet 所
我已经输入了在里面应用程序标签。 当我尝试进行此 Activity 时,我崩溃了。 这是我的java文件: ** import com.google.android.maps.MapActivity;
我试图在 html 文档上使用我的 java 小程序,但它只是一遍又一遍地给出相同的错误。我正在使用 eclipse 。当我调试/运行小程序时,一切正常,但是当我将其导出到 jar 文件并尝试将其与
我有一个 Android 库,我在两个不同的项目中使用它。在其中之一中,我可以正确使用该库。但是,在第二个项目中,我遇到了 NoClassDefFound 异常。 08-31 07: 49:23.15
嗨,当我添加 activation.jar、编译以及运行时出现错误时,我收到 NoClassDefFoundError。 DataHandler 类存在于 activation.jar 注意:我在 a
我有一个扩展 OrmliteSqliteOpenHelper 的类,以便为 Android 应用程序提供持久性模块。问题是,每当我从 Eclipse 中的测试项目访问此类时,它都会抛出 NoClass
我安装了 apache-jmeter-5.1.1 和 java 1.8.0_221 (8),并且正在浏览 getting started guide在 GUI 中构建 Web 测试计划。但是当我单击“
我正在尝试在我的项目中使用 Jira Rest Java 客户端。但无法连接到我安装的 jira。使用以下代码片段时: JiraRestClientFactory factory = new Asyn
我查看了此问题的其他答案,并尝试遵循它们。基本上是这样的场景:我有一个通过 jsp 页面调用的类。该类有一个在 jar 文件中找到的类。当我转到该页面时,对于 jar 中的类,我得到一个未找到类的异常
我最近将 ADT 从 22 版本更新到了 23.0 版本。现在我的项目在更新之前运行良好,但出现以下错误:- 01-01 10:19:27.016: E/AndroidRuntime(2405):
这个问题已经有答案了: TestNG java.lang.NoClassDefFoundError: com/google/common/primitives/Ints (3 个回答) 已关闭 6 年
概念是在特定时间获得通知。显然,我做到了,直到我包含了对低于 HoneyComb 和高于它的版本的支持。 我已经设置了最小 SDK 版本 8 和目标 SDK 17。由于类编码要大得多,我只显示存在问题
我是一名优秀的程序员,十分优秀!