1 2 Previous Next 27 Replies Latest reply on Apr 30, 2010 10:14 AM by kabirkhan Go to original post
      • 15. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
        kabirkhan
        Trying to run the kernel tests with the jboss-reflect snapshot and javassist implementation with security disabled results in loads of failures. A lot of these seem to be due to BeanInfo never having been tested with the Javassist implementation, and fall into the following categories:
        • PropertyInfo.getUnderlyingAnnotation() is not working properly w/ Javassist so we get problems in jbossxb since the @XmlTransient annotation is not read
        • I need to dig in properly, but it seems that when configuring Collection/Map/Array properties, the individual elements are null rather than containing the expected values
        • There might be more

         

        I am currently creating Javassist versions of the org.jboss.test.beaninfo.test.* tests and fixing what comes up. The first thing I found is that when creating property infos for things like

         

        public class BeanInfoGenericInconsistentTypes
        {
           public BeanInfoGenericClass<String> getSomething()
           {
              return null;
           }
        
           public void setSomething(BeanInfoGenericClass<Integer> x)
           {
           }
        }
        

         

        With the Javassist implementation the 'something' property gets both a getter and a setter, while with introspection it gets only a getter. The code that determines this is this in AbstractBeanInfoFactory.getBeanProperties():
                          TypeInfo pinfo = thisSetter.getParameterTypes()[0];
                          if (getter.getReturnType().equals(pinfo) == true)
        
        The introspection implementation returns ParameterizedClassInfos containing the generic information for the parameter and return types, so it looks like I will need to implement that for javassist anyway.
        • 16. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
          kabirkhan

          When testing kernel with the JavassistTypeInfoFactory last week I got quite a few errors due to some tests trying to configure private members. Although the generated javassist joinpoint classes extend sun.reflect.MagicAccessorImpl so they can access private members the javassist compiler fell over when trying to compile the generated classes since they were trying to access private members. I have fixed those errors by implementing https://jira.jboss.org/jira/browse/JBREFLECT-6, so that the JavassistReflectionFactory now generates the bytecode directly.

           

          There are still a few errors when running this in kernel, so I'll try to find what those are. Currently I am running this with security turned off, once that is turned on again there will be more, but I'll do what I can without security first,

          • 17. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
            flavia.rainone

            Kabir Khan wrote:

             

            I have fixed those errors by implementing https://jira.jboss.org/jira/browse/JBREFLECT-6, so that the JavassistReflectionFactory now generates the bytecode directly.

            That's great! I'm curious to see some benchmark results!

            • 18. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
              kabirkhan

              Having revisited how the classpools are set up (http://community.jboss.org/thread/151095) which became apparent after looking into (http://community.jboss.org/message/538568#538568) and fixed the problems to do with generating accessors for classes loaded by a parent of the jboss-reflect classloader I now end up with the following problems when starting AS:

               

              Failed to boot JBoss:
              java.lang.Exception: Encountered exception in server startup
              at org.jboss.bootstrap.impl.mc.server.AbstractMCServerBase.bootstrapMcAndDescriptors(AbstractMCServerBase.java:360)
              at org.jboss.bootstrap.impl.mc.server.AbstractMCServerBase.doStart(AbstractMCServerBase.java:292)
              at org.jboss.bootstrap.impl.as.server.AbstractJBossASServerBase.doStart(AbstractJBossASServerBase.java:381)
              at org.jboss.bootstrap.impl.base.server.AbstractServer$StartServerTask.run(AbstractServer.java:413)
              at java.lang.Thread.run(Thread.java:637)
              Caused by: org.jboss.xb.binding.JBossXBException: Failed to parse source: java.lang.IllegalStateException: java.lang.ClassNotFoundException: org.jboss.beans.metadata.spi.AnnotationMetaData
              at org.jboss.kernel.plugins.deployment.AbstractKernelDeployment.annotations
              at org.jboss.kernel.plugins.deployment.AbstractKernelDeployment
              at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBParser.java:195)
              at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBParser.java:175)
              at org.jboss.xb.binding.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:161)
              at org.jboss.bootstrap.impl.mc.deployer.TempBasicXMLDeployer.deploy(TempBasicXMLDeployer.java:188)
              at org.jboss.bootstrap.impl.mc.server.AbstractMCServerBase.bootstrapMcAndDescriptors(AbstractMCServerBase.java:345)
              ... 4 more
              Caused by: org.jboss.xb.binding.JBossXBRuntimeException: java.lang.IllegalStateException: java.lang.ClassNotFoundException: org.jboss.beans.metadata.spi.AnnotationMetaData
              at org.jboss.kernel.plugins.deployment.AbstractKernelDeployment.annotations
              at org.jboss.kernel.plugins.deployment.AbstractKernelDeployment
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.rethrowWithLocation(JBossXBNoSchemaBuilder.java:2293)
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.createRootElementBinding(JBossXBNoSchemaBuilder.java:428)
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.createRootElements(JBossXBNoSchemaBuilder.java:403)
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.build(JBossXBNoSchemaBuilder.java:273)
              at org.jboss.xb.builder.JBossXBBuilder.build(JBossXBBuilder.java:336)
              at org.jboss.xb.builder.JBossXBBuilder.build(JBossXBBuilder.java:222)
              at org.jboss.xb.builder.JBossXBBuilder.build(JBossXBBuilder.java:201)
              at org.jboss.xb.binding.resolver.AbstractMutableSchemaResolver.resolve(AbstractMutableSchemaResolver.java:315)
              at org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler.startElement(SundayContentHandler.java:177)
              at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.startElement(SaxJBossXBParser.java:370)
              at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
              at org.apache.xerces.xinclude.XIncludeHandler.startElement(Unknown Source)
              at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
              at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
              at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
              at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
              at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
              at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
              at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
              at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
              at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
              at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBParser.java:191)
              ... 8 more
              Caused by: java.lang.RuntimeException: java.lang.IllegalStateException: java.lang.ClassNotFoundException: org.jboss.beans.metadata.spi.AnnotationMetaData
              at org.jboss.reflect.plugins.javassist.JavassistParameterizedClassInfo.findTypeInfo(JavassistParameterizedClassInfo.java:153)
              at org.jboss.reflect.plugins.javassist.JavassistParameterizedClassInfo.getComponentType(JavassistParameterizedClassInfo.java:121)
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.bindProperty(JBossXBNoSchemaBuilder.java:1447)
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateType(JBossXBNoSchemaBuilder.java:1231)
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:855)
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:843)
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateTypeBinding(JBossXBNoSchemaBuilder.java:604)
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.resolveTypeBinding(JBossXBNoSchemaBuilder.java:563)
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.createElementBinding(JBossXBNoSchemaBuilder.java:443)
              at org.jboss.xb.builder.JBossXBNoSchemaBuilder.createRootElementBinding(JBossXBNoSchemaBuilder.java:423)
              ... 28 more
              Caused by: java.lang.IllegalStateException: java.lang.ClassNotFoundException: org.jboss.beans.metadata.spi.AnnotationMetaData
              at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.getTypeInfo(JavassistTypeInfoFactoryImpl.java:852)
              at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.createTypeInfoForTypeArgument(JavassistTypeInfoFactoryImpl.java:910)
              at org.jboss.reflect.plugins.javassist.JavassistParameterizedClassInfo.getActualTypeArguments(JavassistParameterizedClassInfo.java:110)
              at org.jboss.reflect.plugins.javassist.JavassistParameterizedClassInfo.findTypeInfo(JavassistParameterizedClassInfo.java:149)
              ... 37 more
              Caused by: java.lang.ClassNotFoundException: org.jboss.beans.metadata.spi.AnnotationMetaData
              at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
              at java.security.AccessController.doPrivileged(Native Method)
              at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
              at java.lang.ClassLoader.loadClass(ClassLoader.java:315)
              at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:330)
              at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
              at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.delegateToIntrospectionImplementation(JavassistTypeInfoFactoryImpl.java:608)
              at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.get(JavassistTypeInfoFactoryImpl.java:564)
              at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.get(JavassistTypeInfoFactoryImpl.java:455)
              at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.get(JavassistTypeInfoFactoryImpl.java:412)
              at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.getTypeInfo(JavassistTypeInfoFactoryImpl.java:848)
              ... 40 more
              Posting Shutdown Request to the server...
              

               

              The problem here is for parameterized type infos. We currently use the type info of the raw type for the whole parameterized type which will not work for things like java.util.Set<org.jboss.beans.metadata.spi.AnnotationMetaData> since the raw type (Set) comes from the system classpath and thus cannot see the actual type argument classes (AnnotationMetaData is further down in the classloader hierarchy).

               

              Parameterized type infos will need to be cached differently, I'll look at how these are handled in plain java across different classloaders.

              • 19. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
                kabirkhan

                After a few false starts I have managed to reproduce the error described in my last post, and while doing so found another problem to do with caching. Both of these problems are related and have to do with difficulties in determining the correct classloader to use for ParamerizedType.

                 

                1 - Other problem

                Kabir Khan wrote:

                 

                alesj wrote:

                 

                As all of the stuff in Reflect works this way, why is this here a problem?

                Not really a problem, I just wanted to check if the object equality is required. It seems to work that way normally, so I'll do that for this instead as well.

                The problem here is that if I generate some classes in classloader so they don't exist in the main classloader. I generate this set of classes twice in two different classloaders

                 

                public class SomeValue{}
                
                public class SomeSignature
                {
                   public java.util.Set<SomeValue> signature
                   {
                      return null;
                   } 
                }
                

                 

                I generate the classes twice, now if I do something along the lines of

                 

                public void testClasses()
                {
                
                   ClassInfo infoA = getSignatureMethodReturnTypeForClass(loaderA); //One of the loaders loading the classes
                   ClassInfo infoB = getSignatureMethodReturnTypeForClass(loaderB); //Another loader loading the classes
                
                   //These all pass
                   assertEquals(ClassLoader.getSystemClassLoader(), infoA.getRawType().getClassLoader());
                   assertEquals(ClassLoader.getSystemClassLoader(), infoB.getRawType().getClassLoader());
                   assertEquals(loaderA, infoA.getActualTypeArguments[0].getClassLoader());
                
                   //Fails - loader is loaderA
                   assertEquals(loaderB, infoB.getActualTypeArguments[0].getClassLoader());
                
                }
                
                private Type getSignatureMethodReturnTypeForClass(ClassLoader loader)
                {
                generateClasses(getPoolForLoader(loader));
                Class clazz = loader.loadClass("SomeSignature");
                Method m = loader.getMethod("signature");
                Type t = m.getGenericReturnType();  //instance of java.lang.reflect.ParameterizedType
                return getTypeInfoFactory().getTypeInfo(t);
                }
                

                 

                The reason this fails is that the parameterized classinfo is cached against the string representation of the name, i.e. "java.lang.String<SomeValue>". This fails with both the introspection and javassist implementations.

                 

                 

                The root of the problem is this in the entry point to both implementations of TypeInfoFactory, and that ParameterizedType has no getClassLoader() method, so it is currently guessed by defaulting to the one for the raw type. The implementations look something like

                 

                   public TypeInfo getTypeInfo(Type type)
                   {
                      if (type == null)
                         throw new IllegalArgumentException("Null type");
                
                      if (type instanceof ParameterizedType)
                         return getParameterizedType((ParameterizedType) type);
                      ...
                    }
                 
                
                    public void getParameterizedType(ParameterizedType type)
                    {
                        //Check cache
                        ClassLoader loader = type.getRawType().getClassLoader();  // 1
                        TypeInfo cached = checkLoaderCacheForParameterizedType(loader, getName(type)); 
                        if (cached != null)
                           return true;
                
                        //Create parameterized type wrapper
                        TypeInfo rawType = getTypeInfo(type.getRawType());
                        TypeInfo args = new TypeInfo[type.getActualTypeArguments().length];
                        for (int i = 0 ; i < args.length ; i++)
                        {
                           args[i] = getTypeInfo(type.getActualTypeArguments()[i];
                        }
                        ClassInfo info = createParameterizedClassInfo(rawType, args);
                
                        //Cache the lookup
                        cacheParameterizedTypeForLoader(loader, info);
                        return info;
                    }
                

                 

                So what happens is when we try to get the parameterized type for Set<SomeValue> with loaderA it gets cached, but against the classloader of Set, which is the system classloader. When we try to get it with loaderB, it is found, but from the cache for Set's classloader, i.e. the system classloader.

                 

                So maybe caching should be turned off for parameterized types? I have not yet checked what the implications of this would be, but it would mean that object equality checks if used will not work for parameterized types created this way. Or maybe they should be cached against the context classloader instead?

                • 20. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
                  kabirkhan

                  2 - classloader for parameterized type

                   

                  I posted this last night right after my "1 - other problem", but could not see it again today?!?

                   

                  Anyway, for a test still using SomeSignature and SomeValue, but now uses the lazy feature where I do something along the lines of

                   

                  public void testClasses() throws Throwable
                  {
                     generateClasses();
                     ClassInfo info = (Classinfo)getTypeInfoFactory().getTypeInfo(SomeSignature.class);
                  
                     MethodInfo mi = info.getDeclaredMethod("signature", new TypeInfo[0]);
                  
                     ClassInfo returnInfo = mi.getReturnType(); //Constructs the parameterized class info internally
                     TypeInfo[] args = returnInfo.getActualTypeArguments(); //* Lazily loads the type arguments
                  }
                   
                  

                   

                  This fails with the call to returnInfo.getActualTypeArguments()

                   

                  java.lang.IllegalStateException: java.lang.ClassNotFoundException: org.jboss.test.classinfo.test.JavassistParameterizedClassInfoClassLoaderArgumentsTestCaseWithSignature
                       at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.getTypeInfo(JavassistTypeInfoFactoryImpl.java:840)
                       at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.createTypeInfoForTypeArgument(JavassistTypeInfoFactoryImpl.java:898)
                       at org.jboss.reflect.plugins.javassist.JavassistParameterizedClassInfo.getActualTypeArguments(JavassistParameterizedClassInfo.java:115)
                     ....
                  Caused by: java.lang.ClassNotFoundException: org.jboss.test.classinfo.test.JavassistParameterizedClassInfoClassLoaderArgumentsTestCaseWithSignature
                       at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
                       at java.security.AccessController.doPrivileged(Native Method)
                       at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
                       at java.lang.ClassLoader.loadClass(ClassLoader.java:315)
                       at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:330)
                       at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
                       at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:398)
                       at java.lang.Class.forName0(Native Method)
                       at java.lang.Class.forName(Class.java:247)
                       at org.jboss.reflect.plugins.introspection.IntrospectionTypeInfoFactoryImpl.resolveComplexTypeInfo(IntrospectionTypeInfoFactoryImpl.java:434)
                       at org.jboss.reflect.plugins.introspection.IntrospectionTypeInfoFactoryImpl.getTypeInfo(IntrospectionTypeInfoFactoryImpl.java:390)
                       at org.jboss.reflect.plugins.introspection.IntrospectionTypeInfoFactory.getTypeInfo(IntrospectionTypeInfoFactory.java:54)
                       at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.delegateToIntrospectionImplementation(JavassistTypeInfoFactoryImpl.java:620)
                       at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.get(JavassistTypeInfoFactoryImpl.java:547)
                       at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.get(JavassistTypeInfoFactoryImpl.java:454)
                       at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.get(JavassistTypeInfoFactoryImpl.java:411)
                       at org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactoryImpl.getTypeInfo(JavassistTypeInfoFactoryImpl.java:836)
                       ... 23 more
                  
                  

                  The reason is that I am using the classloader of the raw type (i.e. Set) to load up this parameterized type, but obviously SomeValue cannot be found there.

                   

                  One way around this would be in mi.getReturnType() when looking up/creating/caching the parameterized class info to use the classloader of mi.getDeclaringClass().getClassLoader(), which should be able to see all the classes involved. However, I am still stuck on which classloader to use for my previous post.

                  • 21. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
                    kabirkhan

                    Kabir Khan wrote:

                     

                    One way around this would be in mi.getReturnType() when looking up/creating/caching the parameterized class info to use the classloader of mi.getDeclaringClass().getClassLoader(), which should be able to see all the classes involved. However, I am still stuck on which classloader to use for my previous post.

                    This works, however for "1 - other problem" I don't really see a way to determine the classloader. It could be the classloader of the raw type, or the loader of any of the class infos. It might be possible to determine which of the classloaders can see all the generic bounds by brute force, but that will probably

                    a) Be slow

                    b) Might not be possible, i.e. maybe none of the classloaders for any of the bounds are able to load everything.

                     

                    I have tried turning off caching for these parameterized ClassInfos, which causes some of the tests to fail. From what I can see fixing them means having to adjust some of the tests to use assertEquals() instead of assertSame() for parameterized ClassInfos. I think this is necessary, and that the idea of enforcing object equality for parameterized ClassInfos is a misunderstanding :-)

                     

                    Java itself does not seem to reuse the ParameterizedTypes, as shown by this simple passing test:

                     

                    public class DeleteMe extends ContainerTest
                    {
                       public DeleteMe(String name)
                       {
                          super(name);
                       }
                    
                       public Set<String> m1(){return null;}
                    
                       public Set<String> m2(){return null;}
                    
                       public void testType() throws Exception
                       {
                          Type t1 = DeleteMe.class.getDeclaredMethod("m1").getGenericReturnType();
                          Type t2 = DeleteMe.class.getDeclaredMethod("m1").getGenericReturnType();
                    
                          ParameterizedType p1 = assertInstanceOf(t1, ParameterizedType.class);
                          ParameterizedType p2 = assertInstanceOf(t2, ParameterizedType.class);
                    
                          //The param are equal, but not the same
                          assertEquals(p1, p2);
                          assertNotSame(p1, p2);
                    
                          //The raw types are the same
                          assertSame(p1.getRawType(), p2.getRawType());
                          assertEquals(1, p1.getActualTypeArguments().length);
                          assertEquals(1, p2.getActualTypeArguments().length);
                          Class<?> clazz1 = assertInstanceOf(p1.getActualTypeArguments()[0], Class.class);
                          Class<?> clazz2 = assertInstanceOf(p2.getActualTypeArguments()[0], Class.class);
                          assertSame(clazz1, clazz2);
                       }
                    }
                    
                    • 22. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
                      kabirkhan

                            Type t1 = DeleteMe.class.getDeclaredMethod("m1").getGenericReturnType();       Type t2 = DeleteMe.class.getDeclaredMethod("m1").getGenericReturnType();

                      Should be

                       

                            Type t1 = DeleteMe.class.getDeclaredMethod("m1").getGenericReturnType();
                            Type t2 = DeleteMe.class.getDeclaredMethod("m2").getGenericReturnType();

                       

                      but the result is the same

                      • 23. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
                        kabirkhan

                        Some information from Andrew Haley to a mail where I asked him about the class loaders of parameterized types:

                         

                        I don't think that it makes any sense even to talk about the class
                        loader that was used to create a ParameterizedType.  Clearly there was
                        a class loader used to resolve the class names that are passed when a
                        ParameterizedType is created, but I don't think the information is
                        recorded anywhere.

                         

                        The core bug here seems to be that cacheing is being done
                        inappropriately.

                         

                        Can you write a test case, please?  One that demonstrates the bug in

                         

                          //Fails - loader is loaderA
                          assertEquals(loaderB, infoB.getActualTypeArguments[0].getClassLoader());

                         

                        It has to be complete and runnable as a standalone program.

                        • 24. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
                          kabirkhan

                          I have tried turning off caching for these parameterized ClassInfos, which causes some of the tests to fail. From what I can see fixing them means having to adjust some of the tests to use assertEquals() instead of assertSame() for parameterized ClassInfos. I think this is necessary, and that the idea of enforcing object equality for parameterized ClassInfos is a misunderstanding :-)

                          Apart from this local fix in BeanInfoCacheTestCase, all the other places that test object equality for parameterized class infos are in tests written by me as part of JBREFLECT-5, so I think I am safe to readjust the tests

                           

                          [kabir ~/sourcecontrol/jboss-reflect/trunk/jboss-reflect]
                          $svn diff src/test/
                          Index: src/test/java/org/jboss/test/beaninfo/test/BeanInfoCacheTestCase.java
                          ===================================================================
                          --- src/test/java/org/jboss/test/beaninfo/test/BeanInfoCacheTestCase.java     (revision 104118)
                          +++ src/test/java/org/jboss/test/beaninfo/test/BeanInfoCacheTestCase.java     (working copy)
                          @@ -125,16 +125,45 @@
                              {
                                 BeanInfo beanInfo = getConfiguration().getBeanInfo(typeInfo);
                                 ClassInfo typeInfo2 = beanInfo.getClassInfo();
                          -      assertSame(typeInfo, typeInfo2);
                          +      assertClassInfos(typeInfo, typeInfo2);
                              }
                          -
                          +   
                              private void assertClassInfo(ClassInfo typeInfo, String className, ClassLoader cl) throws Exception
                              {
                                 BeanInfo beanInfo = getConfiguration().getBeanInfo(className, cl);
                                 ClassInfo typeInfo2 = beanInfo.getClassInfo();
                          -      assertSame(typeInfo, typeInfo2);
                          +      assertClassInfos(typeInfo, typeInfo2);
                              }
                           
                          +   private void assertClassInfos(TypeInfo typeA, TypeInfo typeB)
                          +   {
                          +      ClassInfo classA = assertInstanceOf(typeA, ClassInfo.class);
                          +      ClassInfo classB = assertInstanceOf(typeB, ClassInfo.class);
                          +      
                          +      if (classA.getRawType() == classA)
                          +         assertSame(classA, classB);
                          +      else
                          +      {
                          +         assertEquals(classA, classB);
                          +         TypeInfo[] argsA = classA.getActualTypeArguments();
                          +         TypeInfo[] argsB = classB.getActualTypeArguments();
                          +         
                          +         if (argsA != null)
                          +            assertNotNull(argsB);
                          +         if (argsB != null)
                          +            assertNotNull(argsA);
                          +         if (argsA == null)
                          +         {
                          +            assertNull(argsB);
                          +            return;
                          +         }
                          +         
                          +         assertEquals(argsA.length, argsB.length);
                          +         for (int i = 0 ; i < argsA.length ; i++)
                          +            assertClassInfos(argsA[i], argsB[i]);
                          +      }
                          +   }
                          +
                              @SuppressWarnings("unchecked")
                              protected Type getType(String type, Class<?> clazz) throws Exception
                              {
                          
                          
                          • 25. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
                            alesj

                            Yeah, the cache based on String was already discussed long ago.

                            Dunno what was the outcome of that debate, but feel free to find it. :-)

                             

                            If this doesn't have any negative impact, and it looks like it doesn't,

                            I don't have anything against changing the equality check.

                             

                            ... but it wouldn't be bad to find that old discusssion ...

                            • 26. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
                              kabirkhan

                              Removing the cache for parameterized types largely works, although I need to fix some StackOverflowErrors when using recursive bound type variables such as

                               

                              public class ClassInfoTypeVariableRecursiveBounded<T extends ClassInfoTypeVariableRecursiveBounded<T>>

                              {

                                 public T genericTypeVariableRecursiveBounded(T param, String s)

                                 {

                                    return null;

                                 }

                               

                              }

                              • 27. Re: JBREFLECT-5 - Implementing generics in JavassistClassInfo
                                kabirkhan

                                Kabir Khan wrote:

                                 

                                Removing the cache for parameterized types largely works, although I need to fix some StackOverflowErrors when using recursive bound type variables such as

                                 

                                public class ClassInfoTypeVariableRecursiveBounded<T extends ClassInfoTypeVariableRecursiveBounded<T>>

                                {

                                   public T genericTypeVariableRecursiveBounded(T param, String s)

                                   {

                                      return null;

                                   }

                                 

                                }

                                This has been fixed. I needed to add this method to ClassInfo

                                   /**
                                    * Gets the type variable if we are a parameterized type which is part of a 
                                    * parameterized type and there is a type variable for this type. This is
                                    * useful in avoiding infinite recursion
                                    * 
                                    * @return the type variable
                                    */
                                   String getTypeVariable();
                                
                                1 2 Previous Next