6 Replies Latest reply on Feb 3, 2004 4:39 PM by jblumenkrantz

    Javassist and JavaWebStart

    jblumenkrantz Newbie

      I have a Swing application that is using Javassist to generate some component classes at startup time. I just switched it over to use Java Web Start to make it easier to deploy, but now the Javassist code has stopped working. Specifically, I'm getting a javassist.NotFoundException on the first call to ClassPool.getDefault().get("myclass"); I know that this class is in the system class path, as it is in the same jar file as the code which is doing the lookup. I'd imagine that Java Web Start uses its own classloader, is it possible that this classloader cannot be accessed by ClassPool? Has anyone else tried using Javassist in WebStart-deployed apps and had any success?

      Thanks in advance
      -Jason Blumenkrantz
      jason.blumenkrantz@geodecapital.com

        • 1. Re: Javassist and JavaWebStart
          ghawkins Newbie

          I have the same problem as jblumenkrantz, and don't want to give up on Javassist. Does anyone have any thoughts?

          • 2. Re: Javassist and JavaWebStart
            Shigeru Chiba Expert

            Can you modiy as following and try again?

            // in javassist/ClassPoolTail.java,

            final class SystemClassPath implements ClassPath {
            Class thisClass;

            SystemClassPath() {
            // old: thisClass = java.lang.Object.class;
            thisClass = this.getClass();
            }
            :
            }

            • 3. Re: Javassist and JavaWebStart
              jblumenkrantz Newbie

              After making that change, ClassPool.get() seems to be working fine, and I'm able to generate my custom subclass, but I'm now getting an error when I call myNewCtClass.toClass() after I'm done with the class generation. The stack trace is as follows, and the class that is not found is identical to the one that failed originally in ClassPool.get(). Might I need to make a similar fix elsewhere?

              Thanks a lot
              -Jason

              java.lang.NoClassDefFoundError: mypackage/cell/Cell

              at java.lang.ClassLoader.defineClass0(Native Method)

              at java.lang.ClassLoader.defineClass(Unknown Source)

              at java.lang.ClassLoader.defineClass(Unknown Source)

              at javassist.ClassPool$LocalClassLoader.loadClass(ClassPool.java:365)

              at javassist.ClassPool.writeAsClass(ClassPool.java:427)

              at javassist.CtClass.toClass(CtClass.java:770)


              • 4. Re: Javassist and JavaWebStart
                Bill Burke Master

                Looks like a classloader problem. Where is mypackage/cell/Cell? Is it in the System classpath? Or is it loaded by some sub-classloader?

                The CtClas.toClass() method uses a custom embedded ClassLoader in which the parent CL is the System classloader.

                My bet is that you will have to create is a subclass of ClassLoader in which you expose a loadClassFromBytes(String name, byte[] bytes) this method would have to call defineClass. The parent classloader of this classloader would have to be:

                Thread.currentThread().getContextClassLoader()

                or

                MyPackage.cell.Cell.class.getClassLoader();

                Am I making sense?

                bill

                • 5. Re: Javassist and JavaWebStart
                  ghawkins Newbie

                  That did the trick, thanks a lot! jblumekrantz, did that solve your problem too?

                  • 6. Re: Javassist and JavaWebStart
                    jblumenkrantz Newbie

                    I got it working fine if I replaced the LocalClassLoader constructor as follows:

                    public LocalClassLoader() {
                    super(Thread.currentThread().getContextClassLoader());
                    }

                    WebStart is using a custom JNLPClassLoader that is apparently getting bypassed otherwise. Ideally I'd create another constructor for ClassPool to define the LocalClassLoader's parent class loader, but this does the trick for now.

                    Thanks
                    -Jason