0

我正在使用 javaassists 在运行时修改类的行为。当我在我的计算机上运行该应用程序时,一切正常。

但是这个应用程序是由用户使用 Java Web Start 启动的,因此必须对应用程序的 .jar 进行签名。当类在运行时被 javaassists 修改并加载

CtClass.toClass() 

启动 SecurityException 的方法:

java.lang.SecurityException: class "com.sch.coberturas.db.CobDao"'s signer information does not match signer information of other classes in the same package

我可以通过将修改后的类隔离在单个类包中来避免它,但这是一个奇怪的解决方案。还有其他解决方法吗?

4

2 回答 2

1

就像 OP 要求的那样,我正在为我的评论创建一个答案。

当您使用 SecurityManager 时,您必须始终提供正在使用的受保护域。有了这些信息,javassist 将能够生成具有相同签名信息的类。

这意味着CtClass.toClass()您应该使用ClassPool.toClass(CtClass ct, java.lang.ClassLoader loader, java.security.ProtectionDomain domain).

javassist javadoc中有关此方法的更多信息

于 2013-03-06T13:14:51.307 回答
0

我想补充一点,如果您要更改的类在它所属的包上有更多类,它也可能引发签名者信息异常。我通过加载它们并将它们添加到我更改课程的同一位置来修复它。

示例

ClassPool pool = ClassPool.getDefault();
pool.insertClassPath( new ClassClassPath( this.getClass() ));
ClassLoader loader = this.getClass().getClassLoader();
ProtectionDomain domain = this.getClass().getProtectionDomain();
CtClass class = pool.get("package1.myChangingClass");
// Here goes the code to change the class;
pool.toClass( class, loader, domain );
//
// Now insert code to pre-load other classes with same domain
CtClass otherClass1 = pool.get("package1.someOtherClass1"); // Gets
pool.toClass( otherClass1, loader, domain );                // Preloads
...
CtClass otherClassN = pool.get("package1.someOtherClassN");
pool.toClass( otherClassN, loader, domain );
//
// To be done for all other classes of the same package that throws
// the signer's information exception, after package1.myChangingClass
// is modified and built.

亲切的问候。

于 2018-03-13T12:11:27.340 回答