简体   繁体   English

如何从不受保护的上下文中加载由 jar2exe 加密或保护的 class 文件,例如 Eclipse Birt?

[英]How to load a class file encrypted or protected by jar2exe from unprotected context, for example, Eclipse Birt?

I used Eclipse Birt Engine 4.4.2 (birt-runtime-4_4_2) in my project, And when i encrypt java classes with Jar2exe, even with not hiding "C:\fx.jar|META-INF*|com\javafx**", Birt Engine class loader is not able to load report handler classes, Is there a way to pass this error?我在我的项目中使用了 Eclipse Birt Engine 4.4.2 (birt-runtime-4_4_2),当我使用 Jar2exe 加密 java 类时,即使没有隐藏“C:\fx.jar|META-INF**|com ",Birt Engine class loader 无法加载报告处理程序类,有没有办法通过这个错误?

    Error.ScriptClassNotFoundError ( 1 time(s) )
detail : org.eclipse.birt.report.engine.api.EngineException: Class com.osyslocal.management.view.report.handler.stimgun.general.ReportHandler not found.
    at org.eclipse.birt.report.engine.executor.EventHandlerManager.loadClass(EventHandlerManager.java:104)
    at org.eclipse.birt.report.engine.executor.EventHandlerManager.getInstance(EventHandlerManager.java:75)
    at org.eclipse.birt.report.engine.executor.EventHandlerManager.getInstance(EventHandlerManager.java:49)
    at org.eclipse.birt.report.engine.script.internal.ScriptExecutor.getInstance(ScriptExecutor.java:195)
    at org.eclipse.birt.report.engine.script.internal.ReportScriptExecutor.handleInitialize(ReportScriptExecutor.java:86)
    at org.eclipse.birt.report.engine.api.impl.EngineTask.loadDesign(EngineTask.java:1962)
    at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.doRun(RunAndRenderTask.java:99)
    at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.run(RunAndRenderTask.java:77)
    at com.osyslocal.management.view.results.analysis.AnalyzeResult.createReport(AnalyzeResult.java:376)
    at com.osyslocal.management.view.ui.ProjectView.showReport(ProjectView.java:1015)
    at com.osyslocal.management.view.results.stimgun.AnalyzeStimgunResult$1.execute(AnalyzeStimgunResult.java:90)
    at mysystem.controller.TaskManager$2.run(TaskManager.java:145)
    at org.eclipse.swt.widgets.RunnableLock.run(Unknown Source)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Unknown Source)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Unknown Source)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
    at org.eclipse.jface.window.Window.runEventLoop(Window.java:826)
    at org.eclipse.jface.window.Window.open(Window.java:802)
    at com.osyslocal.management.view.ui.Main$7.run(Main.java:463)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at com.osyslocal.management.view.ui.Main.main(Main.java:456)
Caused by: java.lang.ClassNotFoundException: com.osyslocal.management.view.report.handler.stimgun.general.ReportHandler
    at org.eclipse.birt.core.framework.URLClassLoader.findClass1(URLClassLoader.java:188)
    at org.eclipse.birt.core.framework.URLClassLoader$1.run(URLClassLoader.java:156)
    at org.eclipse.birt.core.framework.URLClassLoader$1.run(URLClassLoader.java:1)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.birt.core.framework.URLClassLoader.findClass(URLClassLoader.java:151)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at org.eclipse.birt.report.engine.executor.ApplicationClassLoader.loadClass(ApplicationClassLoader.java:79)
    at org.eclipse.birt.report.engine.executor.EventHandlerManager.loadClass(EventHandlerManager.java:99)
    ... 20 more

Problem: According to the solution provided by the jar2exe official website, Every class has a ClassLoader that loads the class.问题:根据jar2exe官网提供的解决方案,每一个class都有一个ClassLoader加载class。

The ClassLoader of protected (encrypted) classes, is a special ClassLoader, while the ClassLoader of unprotected classes is another ClassLoader.受保护(加密)类的ClassLoader是一个特殊的ClassLoader,而不受保护类的ClassLoader是另一个ClassLoader。 When the program is to load a class or resource, it will use the ClassLoader of the current class by default, such as "Class.forName()".当程序要加载一个class或资源时,会默认使用当前class的ClassLoader,如“Class.forName()”。 So in the Eclipse Birt program is to load protected resource within an unprotected class, the ClassLoader of the unprotected class cannot load the protected resources.所以在Eclipse Birt程序中是在一个未受保护的class中加载受保护的资源,未受保护的class的ClassLoader无法加载受保护的资源。 In this problem, the program tried to load ReportHandler class from an unprotected ApplicationClassLoader class.在这个问题中,程序尝试从未受保护的 ApplicationClassLoader class 加载 ReportHandler class。

Solution: When a generated exe file runs, The context ClassLoader of the current thread, is a Special ClassLoader.解决方法:生成的exe文件运行时,当前线程的上下文ClassLoader,是一个Special ClassLoader。 So we tried to download the source of Eclipse Birt Engine and then changed the body of loadClass(className) method of ApplicationClassLoader class and replaced the following line:于是我们尝试下载Eclipse Birt Engine的源码,然后修改ApplicationClassLoader class的loadClass(className)方法体,替换为以下行:

Thread.currentThread().getContextClassLoader().loadClass(className);

Therefore the program sends the className as an argument containing the FQDN of the protected class (ReportHandler).因此,程序将 className 作为包含受保护 class (ReportHandler) 的 FQDN 的参数发送。 Then successfully the modified and compiled ApplicationClassLoader class in the Eclipse Birt jar file runs the program without failure.然后成功修改并编译Eclipse Birt jar文件中的ApplicationClassLoader class文件运行程序没有失败。 The final edited version of the method is as follows:该方法的最终编辑版本如下:

public Class loadClass( String className ) throws ClassNotFoundException
    {
        return Thread.currentThread().getContextClassLoader().loadClass(className);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM