0

i'm using javaassists to modify the behaviour of a class in runtime. When i run the app in my computer all works fine.

But this app is launched by the users with Java Web Start, so that the .jar of the app must be signed. When the class is modified in runtime time by javaassists and loaded with the

CtClass.toClass() 

method a SecurityException is launched:

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

I can avoid it by isolating the modified class in a single class package, but this is a weird solution. Is there another workarround?

Charles
  • 50,943
  • 13
  • 104
  • 142
Telcontar
  • 4,794
  • 7
  • 31
  • 39
  • Possible duplicate of http://stackoverflow.com/questions/2877262/java-securityexception-signer-information-does-not-match – n1ckolas Feb 27 '13 at 10:04
  • 1
    No, all the classes are signed by the same certificate, otherwise the app would not start by Java Web Start. The problem is because javaassists modify the class at runtime so that the sign is not valid at runtime (fortunately the sign verificación by java web start is before the start of the app) and not match the sign of the others classes in the same package – Telcontar Feb 27 '13 at 10:18
  • 1
    What about if instead of using `CtClass.toClass()` you use the `ClassPool.toClass(CtClass ct, java.lang.ClassLoader loader, java.security.ProtectionDomain domain))` giving has protection domain the original's class protection domain? That way the generated class should be signed with the same info has the original one (check javadoc: http://www.csg.is.titech.ac.jp/~chiba/javassist/html/javassist/ClassPool.html#toClass(javassist.CtClass, java.lang.ClassLoader, java.security.ProtectionDomain) – pabrantes Mar 01 '13 at 14:56
  • Hi pabrantes, this solution works like a charm. Could you post it in an answer so i can mark it as the solution? – Telcontar Mar 05 '13 at 11:51
  • @Telcontar: glad I could help, I added the answer so you can accept it – pabrantes Mar 06 '13 at 13:15

2 Answers2

1

Like OP requested I'm creating an answer regarding my comment.

When you are using a SecurityManager you must always provide the protected domain in use. With this information javassist will be able to be generate classes with the same signing information.

This means that instead of using CtClass.toClass() you should use ClassPool.toClass(CtClass ct, java.lang.ClassLoader loader, java.security.ProtectionDomain domain).

More information about this method in javassist javadoc

pabrantes
  • 2,161
  • 1
  • 28
  • 34
0

I'd just like to add, that if the class you're changing has more classes on the package it belongs it may throw a signer's information exception also. I fixed it by loading them and adding them in the same spot I changed my class.

Example:

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.

Kind regards.