java - Reflections returning Set with null elements -
i'm using reflections find classes have specific annotation. project structure following
one war package: web-inf/classes/...packages.../classannoted1.class
one jar package included war has class executes code:
reflections reflections= new reflections(classpathhelper.forwebinfclasses(servletcontext)) set set= reflections.gettypesannotatedwith(customannotation.class)
customannotation present on jar package.
the set size correct (ie if have 3 classes annotation in war jar, set size comes 3), elements inside null instead of class. need class , check annotation parameters inside class of jar.
anyone got idea of why happening?
edit:
reflections reflections= new reflections("com.my.customannotededclasses"); //package annoted class in set set= reflections.gettypesannotatedwith(customannotation.class);
also not work, in case set length 0 instead of number of classes annotation.
edit 2: ok, real problem was packaging whole application ear had following:
ear ----> war ----> jar
the jar included in ear lib folder , not on war lib folder. jar classes couldn't see war classes, once made war depend on jar directly this:
ear ----> war ---------> jar
it started working. original question still stands, there might situations want jar classes included in ear instead of war (if have multiple wars need use jar instance).
i guess can't using reflections library. did hand:
public static list<class<?>> getclassesannotatedwith(class annotation, servletcontext servletcontext) { list<class<?>> webclasses, jarclasses; webclasses= getclassesannotedwithfromclassloader(annotation, servletcontext.getclassloader()); jarclasses= getclassesannotedwithfromclassloader(annotation, thread.currentthread().getcontextclassloader()); (class<?> jarclass : jarclasses) { class<?> elementtoadd= null; (class<?> webclass : webclasses) { if ( ! jarclass.getname().equals(webclass.getname())) { elementtoadd= jarclass; } } if(elementtoadd != null) { webclasses.add(elementtoadd); } } return webclasses; } private static list<class<?>> getclassesannotedwithfromclassloader(class annotation, classloader classloader) { list<class<?>> classes= new arraylist<class<?>>(); class<?> classloaderclass= classloader.getclass(); while (! classloaderclass.getname().equals("java.lang.classloader")) { classloaderclass= classloaderclass.getsuperclass(); } try { field fldclasses= classloaderclass.getdeclaredfield("classes"); fldclasses.setaccessible(true); vector<class<?>> classesvector= (vector<class<?>>) fldclasses.get(classloader); (class c : classesvector) { if (c.isannotationpresent(annotation)) { classes.add(c); } } } catch (exception e) { } return classes; }
i classloader war package through servletcontext object. there protection in case class defined in both war , jar annotation , same name (you should check if packages same though).
note should never use code in own projects (maybe debugging). involves reflecting classloader class make "classes" property public. property might not exists in java 9 example, beware. might have security problems if interacting modules written third parties.
Comments
Post a Comment