1 2 Previous Next 15 Replies Latest reply on Nov 3, 2004 10:02 AM by chiba

    unable to locate the proper class - and some newbie question

    alvlim1982

      Greetings,
      I'm a beginner in Java and also Javassist. It's a very great tool.

      I have a question. Currently I'm trying to learn Javassist by following the tutorial provided by Mr.Chiba and I encountered few problems.

      1- The ClassPool failed to locate the proper class file unless I specify the full path of the class location, eg -> ./build/classes/com/org/solution/....
      --------------------------------------------------------------------
      Below is my code :
      ClassPool pool = ClassPool.getDefault();

      pool.insertClassPath("./build/classes/com/org/solution/javaAssist/test");

      CtClass clas = pool.get("StringBuilder");
      --------------------------------------------------------------------
      Is there any other more convenient way? For example, to make the classLoader automatically refer to the path where I put my compiled classes.

      2- When I call writeFile(), it will write the modified file into the root directory. Again, is there any other way besides explicitly put the destination where I want to put the newly modified file by calling writeFile(java.lang.String directoryName).

      3- Pruning and Frozen. What does these 2 mean? I know frozen means you can no longer modify the class whereas pruning is you can no longer read or load it. Is my assumption correct?

      Hope you guys can help. I've tried to read through the forum, but I really need help quite urgently for my project.
      Thanks in advance.


      Cheers,
      Alvin Lim
      * someone who has only 3 months working experience ;) *

        • 1. Re: unable to locate the proper class - and some newbie ques
          alvlim1982

          hi again,
          seems like no1 answer my questions :( maybe its too simple.

          anyway, i have another doubt over here. my current situation is to generate value object in runtime from a set of configuration files. I tried to add a new field inside........but I found out that there's no CtClass.stringType or any String relevant type inside. So what if I wanted to add something like "private String name" inside the newly generated VO?

          and how bout the modifier. How can I set the modified of the field?

          Hope someone can help me. Thanks in advance.

          • 2. Re: unable to locate the proper class - and some newbie ques
            chiba

            Wow, many questions! :)


            1- The ClassPool failed to locate the proper class file unless I specify the full path of the class location, eg -> ./build/classes/com/org/solution/....

            Javassist uses CLASS_PATH. The real problem in your code is not
            the class path.
            CtClass clas = pool.get("StringBuilder");

            This is unfortunately wrong. All the class names must be fully
            qualified. So you had needed to say "com.org.solution/javaAssist/test/StringBuilder".

            (I have a plan to introduce a mechanism similar to import, though.)


            is there any other way besides explicitly put the destination where I want to put the newly modified file by calling writeFile(java.lang.String directoryName).


            ... Do you really need a way to change the default root directory?
            I appreciate if you are satisfied with writeFile(String)... :)


            3- Pruning and Frozen. What does these 2 mean? I know frozen means you can no longer modify the class whereas pruning is you can no longer read or load it. Is my assumption correct?


            yes, frozen means you cannot modify the class.
            Pruning means method bodies in CtClass has been deleted to save
            memory space. This is becaues some users said they processed a
            large number of class files and thus caused memory shortage.
            You can still read member signatures of pruned CtClass.

            However, people including Bill Burke do not seem to like pruning.
            This memory space optimization might be turned off in the next
            release. :< (pruning is off in the current HEAD in CVS.)

            Chiba


            • 3. Re: unable to locate the proper class - and some newbie ques
              chiba

              Oops, another two questions.


              but I found out that there's no CtClass.stringType or any String relevant type inside. So what if I wanted to add something like "private String name" inside the newly generated VO?


              Use ClassPool#get.
              ClassPool pool = ... ;
              CtClass stringType = pool.get("java.lang.String");
              


              Or use CtField#make.

              CtClass cc = ... ;
              CtField f = CtField.make("private java.lang.String name;", cc);
              cc.addField(f);
              


              Chiba

              • 4. Re: unable to locate the proper class - and some newbie ques
                alvlim1982

                Hi,
                Thanks a lot for the reply Mr.Chiba. Really appreciate it. Anyway, perhaps i'm a problematic person, coz i have more questions for u. *lol*

                Ok, I have actually solved the previous questions....and here it is, some new problems.

                My current program works like this (value obj generation) :

                1. Input value is the name of the Vo to generate.

                2. Check whether it is inside a map.

                3. If yes, get the CtClass from the map, use
                clas = ctClass.toClass();
                return (ValueObject) clas.newInstance();

                4. If no, then generate the class by adding fields, methods, etc. Then return the class by doing the same thing as in (3).

                5. I tested to first, call the VO, and since it doesnt exist, it is generated, then i again, call the VO, and it found that it is already in the map, so it load from the map then the problem occurs.

                Below is the msg:

                javassist.CannotCompileException: by java.lang.LinkageError: duplicate class definition: com/PersonVO
                at javassist.CtClass.toClass(CtClass.java:950)
                at javassist.CtClass.toClass(CtClass.java:910)
                at com.generateProxy(ValueObjectTransformer.java:58)
                at com.main(VOGeneratorTest.java:43)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                at java.lang.reflect.Method.invoke(Method.java:324)
                at com.intellij.rt.execution.application.AppMain.main(Unknown Source)

                Sorry if the msg is a bit messy.
                Also, when i tried to use -->

                Loader c1 = new Loader(pool);
                Class abc = c1.loadClass(some class path n name);
                return (ValueObject) abc.newInstance();

                It throws ClassCastException

                Sorry for asking too much :D Thx in advance!

                Cheers,
                ALvin Lim

                • 5. Re: unable to locate the proper class - and some newbie ques
                  chiba

                   

                  javassist.CannotCompileException: by java.lang.LinkageError: duplicate class definition: com/PersonVO


                  This means the class loader has been already loaded PersonVO and
                  thus it cannot load your modified version of PersonVO. I guess your
                  code includes PersonVO as a type name.

                  Loader c1 = new Loader(pool);
                  Class abc = c1.loadClass(some class path n name);
                  return (ValueObject) abc.newInstance();


                  It throws ClassCastException


                  This is a problem called version barrier. You cannot cast a class type
                  into another one loaded by another class loader.

                  For more details, please read section 3.2 of the Javassist tutorial.

                  Chiba

                  • 6. Re: unable to locate the proper class - and some newbie ques
                    alvlim1982

                    Hi Mr. Chiba,
                    Thanks for your reply. I think I get what you mean. I somehow modified my VO generator so that it only loads the object once and store in somewhere (not efficient, but that's the only way I can think of to bypass the class loading stuff).

                    Really thanks a lot. I'll post more questions here if I don't understand something.

                    Thanks alot.

                    Cheers,
                    Alvin Lim

                    • 7. Re: unable to locate the proper class - and some newbie ques
                      alvlim1982

                      I have another question here.
                      Let say we have a modified class in JVM A, so if we are to pass the modified class to JVM B through RMI, will it cause any problem?
                      Or maybe you have any better suggestion to do this?

                      Thanks in advance

                      • 8. Re: unable to locate the proper class - and some newbie ques
                        alvlim1982

                        Hi again,
                        I have another problem (again...never ending problems). This time, I really really have no idea what is happening.

                        As I've said earlier, I tried to use javassist to generate run-time Value Object (there's no physical file). Then after that, I will pass the instance of the newly generate VO through EAI (then to DB). Some weird errors occurred. Even if I somehow provide the physical class.........the error is the same.

                        ----------------------------------------------------------
                        java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
                        java.lang.ClassNotFoundException: com.temp.EmployeeVO: This error could indicate that a component was deployed on a cluster member but not other members of that cluster. Make sure that any component deployed on a server that is part of a cluster is also deployed on all other members of that cluster
                        at weblogic.rjvm.BasicOutboundRequest.sendReceive(BasicOutboundRequest.java:108)
                        at weblogic.rmi.cluster.ReplicaAwareRemoteRef.invoke(ReplicaAwareRemoteRef.java:284)
                        at weblogic.rmi.cluster.ReplicaAwareRemoteRef.invoke(ReplicaAwareRemoteRef.java:244)
                        at com.ejb.CommonGenericEJB_e1n9qi_EOImpl_813_WLStub.callEAIManager(Unknown Source)
                        at com.ORBSPerformanceTest.testManualInsert(ORBSPerformanceTest.java:119)
                        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                        at java.lang.reflect.Method.invoke(Method.java:324)
                        at junit.framework.TestCase.runTest(TestCase.java:154)
                        at junit.framework.TestCase.runBare(TestCase.java:127)
                        at junit.framework.TestResult$1.protect(TestResult.java:106)
                        at junit.framework.TestResult.runProtected(TestResult.java:124)
                        at junit.framework.TestResult.run(TestResult.java:109)
                        at junit.framework.TestCase.run(TestCase.java:118)
                        at junit.framework.TestSuite.runTest(TestSuite.java:208)
                        at junit.framework.TestSuite.run(TestSuite.java:203)
                        at junit.textui.TestRunner.doRun(TestRunner.java:116)
                        at com.intellij.rt.execution.junit2.IdeaJUnitAgent.doRun(Unknown Source)
                        at junit.textui.TestRunner.start(TestRunner.java:172)
                        at com.intellij.rt.execution.junit.TextTestRunner2.startRunnerWithArgs(Unknown Source)
                        at com.intellij.rt.execution.junit2.JUnitStarter.prepareStreamsAndStart(Unknown Source)
                        at com.intellij.rt.execution.junit2.JUnitStarter.main(Unknown Source)
                        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                        at java.lang.reflect.Method.invoke(Method.java:324)
                        at com.intellij.rt.execution.application.AppMain.main(Unknown Source)
                        ----------------------------------------------------------

                        I really ran out of ideas trying to solve this thing. Please help, i need them desperately.

                        Thanks.

                        • 9. Re: unable to locate the proper class - and some newbie ques
                          chiba

                          I don't have any idea. Have you considered this?

                          java.lang.ClassNotFoundException: com.temp.EmployeeVO: This error could indicate that a component was deployed on a cluster member but not other members of that cluster. Make sure that any component deployed on a server that is part of a cluster is also deployed on all other members of that cluster



                          • 10. Re: unable to locate the proper class - and some newbie ques
                            alvlim1982

                            Hi again,
                            I donno whether the problem is with the way I deploy my project. My entire project is an EJB (web application). Thus, when I run my project, it is in EJB. THus when I JAR my project into an EJB, the compiler can only JAR whatever classes I have and not those that have not been generated.

                            If I am to use on-the-fly byte code generation, it will cause error since there is no physical class reference to be JAR-ed inside the EJB.

                            I somehow changed it to pregenerated classes, so that when i deploy the EJB, those classes have already been generated physically and are deployed together with the rest of the classes. Then it's running fine, no error. :T

                            haha, is there any other better way of doing this?

                            Thanks again and sorry for taking too much of ur time here.

                            • 11. Re: unable to locate the proper class - and some newbie ques
                              chiba

                              Generating physical class files in advance
                              is the simplest way. Otherwise, you might
                              be able to modify a class loader that loads
                              your EJB so that the class loader also can find
                              "virtual" class files generated on the fly.

                              • 12. Re: unable to locate the proper class - and some newbie ques
                                alvlim1982

                                Hi Chiba,
                                Thanks for your reply. Currently we're using weblogic server to deploy our EJB. If we are to do the 2nd approach, means we're to modify the class loader of the EJB inside weblogic or maybe somehow create a new one to replace it (which I have no idea how to).

                                Anyway, I guess I don't have any option since time is limited but I would really like to know how can I do the 2nd approach. ;)

                                Thanks a lot Mr Chiba. You really helped me out a lot.

                                • 13. Re: unable to locate the proper class - and some newbie ques
                                  chiba

                                  I think JBoss has API to substitute a user-defined
                                  class loader for the original one. WebLogic should
                                  have such a API... :-p

                                  Chiba

                                  • 14. Re: unable to locate the proper class - and some newbie ques
                                    alvlim1982

                                    Hi again,
                                    I donno whether weblogic has such thing, but I will try to find out.

                                    Another question, hehe, hope I am not causing you too much troubles with so many questions.

                                    How do I accommodate for data types like char[] or byte[].... :D

                                    Thanks again in advance

                                    1 2 Previous Next