Мы создаем пользовательский загрузчик классов на основе javassist, модифицируя байт-код некоторых классов при загрузке. Частью проекта является также подписанный фляга, содержащая провайдера безопасности.
Инициализация загрузчика выглядит следующим образом:
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
экземпляр?