我们正在创建一个基于javassist的自定义类加载器,在加载时修改一些类字节代码。该项目的一部分也是一个包含安全提供者的签名jar。
Loader的初始化看起来如下:
private final Loader initLoader(ClassLoader master) {
final ClassPool pool = ClassPool.getDefault();
final Loader loader = new Loader(master, pool);
try {
loader.addTranslator(pool, new MyTranslator());
} catch (Exception e) {
e.printStackTrace();
}
return loader;
}
MyTranslator
类执行修改但不关心安全相关类。 master
是系统(父)类加载器。
当应用程序在加载相关安全类时到达该部分时,抛出此异常:
Caused by: java.security.NoSuchProviderException: JCE cannot authenticate the provider EXAMPLE-PROV
at javax.crypto.JceSecurity.getInstance(JceSecurity.java:100) ~[?:1.8.0_121]
at javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:230) ~[?:1.8.0_121]
at my.example.app.security.ExampleKeyAgreement.generateSharedSecret(ExampleKeyAgreement.java:56) ~[?:?]
... 22 more
Caused by: java.util.jar.JarException: Class is on the bootclasspath
at javax.crypto.JarVerifier.verify(JarVerifier.java:286) ~[?:1.8.0_121]
at javax.crypto.JceSecurity.verifyProviderJar(JceSecurity.java:159) ~[?:1.8.0_121]
at javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:185) ~[?:1.8.0_121]
at javax.crypto.JceSecurity.getInstance(JceSecurity.java:97) ~[?:1.8.0_121]
at javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:230) ~[?:1.8.0_121]
at my.example.app.security.ExampleKeyAgreement.generateSharedSecret(ExampleKeyAgreement.java:56) ~[?:?]
我的问题是,如果有办法从自定义类加载器加载这些类而不违反java安全机制?
方法javassist.Loader#setDomain(ProtectionDomain)
说
如果没有注册适当的保护域,此加载程序加载的程序将无法与安全管理器或签名的jar文件一起使用。
如何创建或确定有效的ProtectionDomain
实例?