【问题标题】:How to load a class file encrypted or protected by jar2exe from unprotected context, for example, Eclipse Birt?如何从不受保护的上下文中加载由 jar2exe 加密或保护的类文件,例如 Eclipse Birt?
【发布时间】:2021-04-28 08:23:36
【问题描述】:

我在我的项目中使用了 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

【问题讨论】:

    标签: java eclipse exe classloader birt


    【解决方案1】:

    问题: 根据jar2exe官网提供的解决方案,每个类都有一个加载类的ClassLoader。

    受保护(加密)类的ClassLoader是一个特殊的ClassLoader,而不受保护类的ClassLoader是另一个ClassLoader。当程序要加载一个类或资源时,会默认使用当前类的ClassLoader,如“Class.forName()”。所以在Eclipse Birt程序中是在一个不受保护的类中加载受保护的资源,不受保护的类的ClassLoader不能加载受保护的资源。在这个问题中,程序试图从一个未受保护的 ApplicationClassLoader 类中加载 ReportHandler 类。

    解决方案: 当生成的exe文件运行时,当前线程的上下文ClassLoader,是一个Special ClassLoader。于是我们尝试下载了Eclipse Birt Engine的源码,然后修改了ApplicationClassLoader类的loadClass(className)方法体,替换了下面这行:

    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);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 2014-12-16
      • 2021-03-28
      • 2010-09-22
      • 2012-09-06
      • 1970-01-01
      相关资源
      最近更新 更多