我希望能够在(未签名的)applet中生成和加载自定义类。生成它我可以处理,但我正在与安卓管理器进行斗争,它似乎不希望我加载它们。
这是一个视觉概述;你可以看到我坚持第二阶段:
我最初打算使用自定义类加载器。显然这在applet中是不允许的; ClassLoader构造函数抛出SecurityException。
然后我考虑直接在另一个类加载器上调用ClassLoader.defineClass(String name, byte[] b, int off, int len),但该方法受到保护。
我尝试通过反射访问该方法。我的希望并不高,但我尝试了它,确实也抛出了一个SecurityException。
URLClassLoader似乎提供了救赎:它有一个静态工厂创建方法,不会抛出任何安全异常。但是,该技术不允许对加载器进行子类化或访问受保护的defineClass方法。它只接受一组URL对象。
所以我尝试将URL子类化为覆盖其openConnection方法,以此方式返回我的类字节,但URL类是最终的。
然后我尝试使用重写的openConnection方法创建自定义URLStreamHandler并将其传递给URL的构造函数。 SecurityManager再次提出了这个问题。
然后我尝试使用自定义工厂调用URL.setStreamHandlerFactory,该工厂将返回我的自定义流处理程序。再次有安全管理器抱怨,因为如果不抱怨还有什么好处呢?
然后我尝试创建javax.management.loading.MLet。我不知道它是什么,但它是URLClassLoader的子类,它允许在其构造函数中指定一个自定义URLStreamHandlerFactory,并且没有提到抛出安全异常,但它仍然无论如何。
在绝望中,我尝试使用自定义ProxySelector调用ProxySelector。setDefault,希望能够拦截URL并以某种方式将其路由回我的applet,但我也没有权限。
我尝试通过java.system.class.loader
标记设置<param name="java_arguments" ...>
属性,但它似乎不是尊贵的属性之一。
最后,我能想到的唯一剩下的方法是将我的类字节发送到远程服务器,该服务器将生成一个临时URL,我可以将其与URLClassLoader.newInstance(URL []一起使用) )。这会有效,但我真的不喜欢这个想法。看起来它很快就会变得复杂,不同的ClassLoader的交互,并且服务器依赖对我想做的事情来说并不实用。 显然,SecurityManager很高兴让你创建一个URLClassLoader,但在尝试使用它时会自发沮丧。
我会喜欢在普通的unsigned applet安全沙箱中执行此操作,如果可能的话,那么体验是无缝的。
但大多数情况下我只是感到困惑,因为如果它不可能那就毫无意义。 如果SecurityManager对从任意外部URL加载类感到高兴,那么它不应该介意从局部变量中的字节数组中加载一个。 该限制仍然是荒谬的。代码仍然是内部和沙盒。
它对于动态代码生成和实现自定义JAR压缩(如LZMA压缩)都很有用。
帮助!
答案 0 :(得分:1)
..安全管理器再次抱怨,因为如果不抱怨还有什么好处呢?
这是为了保护最终用户,而不是做你正在尝试的各种事情。
..如何加载课程?
签署Jar,让用户接受经过数字签名的代码。
..将我的类字节发送到远程服务器,该服务器将生成一个临时URL,我可以将其与URLClassLoader.newInstance(URL [])结合使用。
沙盒小程序无法创建URLClassLoader
。