@SuppressWarnings("unchecked") private <T> ConcreteEntityDescriptor<T> createConcreteEntityDescriptor( Class<?> c, EntityDescriptorStore store, Map<Type, Class<?>> types) throws IOException { // parent of the entity Class<?> parentClass = c.getSuperclass(); ConcreteEntityDescriptor<?> parent = null; while (parentClass != null) { Entity parentAnnotation = parentClass.getAnnotation(Entity.class); if (parentAnnotation != null) { parent = createConcreteEntityDescriptor(parentClass, store, types); break; } parentClass = parentClass.getSuperclass(); } // @Entity Entity annotation = c.getAnnotation(Entity.class); InputStream in = null; try { // bug 1739760 in = c.getResourceAsStream("/" + c.getName().replace('.', '/') + ".class"); if (in == null) { throw new IllegalArgumentException("cannot find bytecode for " + c); } ClassReader reader = new ClassReader(in); EntityClassVisitor visitor = new EntityClassVisitor(c, store, types); reader.accept(visitor, true); visitor.verify(); // getting the descriptor EntityDescriptor<?> descriptor = visitor.getDescriptor(parent); store.put(c, descriptor); // is this entity inlineable? if (annotation.inline()) { if (!descriptor.isInlineable()) { throw new IllegalArgumentException( "entity '" + descriptor.getReturnedClass() + "' is not inlineable." + " An entity is inlineable only if it has one property."); } } return (ConcreteEntityDescriptor<T>) descriptor; } finally { if (in != null) { in.close(); } } }