如何解决如何从不受保护的上下文例如 Eclipse Birt加载由 jar2exe 加密或保护的类文件?
我在我的项目中使用了 Eclipse Birt Engine 4.4.2 (birt-runtime-4_4_2),当我用 Jar2exe 加密 java 类时,即使没有隐藏 "C:\fx.jar|META-INF*|com\ javafx**" ,Birt Engine类加载器无法加载报告处理程序类,有没有办法传递这个错误?
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
解决方法
问题: 根据jar2exe官网提供的解决方案,每个类都有一个加载类的ClassLoader。
受保护(加密)类的类加载器,是一个特殊的类加载器,而不受保护的类的类加载器是另一个类加载器。当程序要加载一个类或资源时,它会默认使用当前类的ClassLoader,比如“Class.forName()”。所以在Eclipse Birt程序中是在一个未受保护的类内加载受保护的资源,不受保护的类的ClassLoader无法加载受保护的资源。在这个问题中,程序试图从不受保护的 ApplicationClassLoader 类加载 ReportHandler 类。
解决办法: 生成的exe文件运行时,当前线程的context ClassLoader,是一个Special ClassLoader。于是我们尝试下载Eclipse Birt Engine的源码,然后把ApplicationClassLoader类的loadClass(className)方法的body改成下面一行:
Thread.currentThread().getContextClassLoader().loadClass(className);
因此,程序将 className 作为包含受保护类 (ReportHandler) 的 FQDN 的参数发送。然后在Eclipse Birt jar文件中修改编译的ApplicationClassLoader类成功运行程序,没有失败。该方法的最终编辑版本如下:
public Class loadClass( String className ) throws ClassNotFoundException
{
return Thread.currentThread().getContextClassLoader().loadClass(className);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。