reflections icon indicating copy to clipboard operation
reflections copied to clipboard

[0.10.2] Reflections do not detect classes with Java 11.0.16+

Open cech12 opened this issue 3 years ago • 6 comments

I am using your library (reflections 0.10.2) in a Wildlfy (24.0.1) environment. My application is packed in an EAR file. The reflection code lies in a WAR inside of the EAR and should detect annotations of the JAR files next to it in the EAR.

With Java 11.0.15 it works good but with the update to 11.0.17 (and to 11.0.16 as well) it does not find the classes of the JAR files. It only detects the classes of the WAR itself.

I use the following code:

Reflections reflections = new Reflections("mypackage", Scanners.TypesAnnotated);
Set<Class<?>> classes = new HashSet<>(reflections.getTypesAnnotatedWith(MyAnnotation.class));

Maybe it has something to do with #373 but the workarounds do not work for me and a downgrade to Java 11.0.15 works.

I tested the JDKs of Temurin (11.0.15, 11.0.16, 11.0.17) and GraalVM (22.1.0 [11.0.15], 22.2.0 [11.0.16], 22.3.0 [11.0.17]). Temurin 11.0.15 and GraalVM 22.1.0 are not producing the issue, the others do.

I hope, you can help me. :)

cech12 avatar Nov 02 '22 06:11 cech12

Same issue on openJDK 17.0.5 ... scan does not work with this version. After downgrade to 17.0.1 scanning works fine.

After some investigation I found out, that the problem is in JboosDir class which throws ClassCastException instead of returning correct instance of Vfs.Dir class.

JDK 17.0.5 extended content-type list (added application/jar-archive) which causes this ClassCastException in the end.

I used this workaround for now:


Vfs.addDefaultURLTypes(new CustomVfsUrlType());

CustomVfsUrlType:


    static class CustomVfsUrlType implements Vfs.UrlType {

        @Override
        public boolean matches(URL url) {
            return url.getProtocol().equals("vfs");
        }

        @Override
        public Vfs.Dir createDir(URL url) throws Exception {
            var virtualFile = url.openConnection().getContent();
            if (virtualFile instanceof VirtualFile) {
                return JbossDir.createDir(url);
            } else {
                Constructor<JbossDir> constructor = JbossDir.class.getDeclaredConstructor(VirtualFile.class);
                constructor.setAccessible(true);
                return constructor.newInstance(VFS.getChild(VFSUtils.toURI(url)));
            }
        }
    }

This is definitely not clean approach. The method JbossDir.createDir should be redefined, but I'm not sure how to get VirtualFile from VirtualJarFileInputStream.

slovi avatar Nov 02 '22 16:11 slovi

So, it has something to do with this issue? https://github.com/ronmamo/reflections/issues/395

Then, a commit https://github.com/ronmamo/reflections/commit/7ccde6e7b6d8cc2e3f8fea4d7d3b3d2677214be2 and PR https://github.com/ronmamo/reflections/pull/396 were made. A merge is planned for 0.10.3 https://github.com/ronmamo/reflections/pull/418.

cech12 avatar Nov 10 '22 09:11 cech12

Yes, It seems that commit 7ccde6e7b6d8cc2e3f8fea4d7d3b3d2677214be2 will fix also this issue.

slovi avatar Nov 10 '22 09:11 slovi

@slovi Your workaround works for me! Thanks for that! :) I hope, the 0.10.3 version will be released soon to remove that hack^^

cech12 avatar Nov 10 '22 13:11 cech12

I yesterday forked the project and tried the suggested bugfix https://github.com/ronmamo/reflections/commit/7ccde6e7b6d8cc2e3f8fea4d7d3b3d2677214be2 for issues (#395, #440, #427) However it did not help the error still occurs. Thus I completely removed the reflection lib and replaced the functionality with something else...

Lonzak avatar Jun 16 '23 13:06 Lonzak

Maybe interesting for you to solve the issue:

I had a similar problem java.lang.ClassCastException: class org.jboss.vfs.VirtualJarInputStream cannot be cast to class org.jboss.vfs.VirtualFile in the context of Java 11.0.20 and WildFly Core 10.1.18.Final-redhat-00001 (in a Redhat EAP 7.3.6 GA). Instead of VirtualFile virtualFile = (VirtualFile) url.openConnection().getContent(); I used VirtualFile virtualFile = org.jboss.vfs.VFS.getChild(url.toURI()); (no cast necessary) and it seems to do the job...

In Redhat EAP 7.4.11 GA (WildFly Core 15.0.26.Final-redhat-00001) the ClassCastException does not occur (there, url.openConnection().getContent() is a VirtualFile; however, org.jboss.vfs.VFS.getChild(url.toURI()) still works there as well).

michaelMarquard avatar Aug 31 '23 14:08 michaelMarquard