{"id":694,"date":"2012-11-30T11:58:55","date_gmt":"2012-11-30T10:58:55","guid":{"rendered":"https:\/\/blogs.ua.es\/miguelon\/?p=694"},"modified":"2012-11-30T11:58:55","modified_gmt":"2012-11-30T10:58:55","slug":"conseguir-la-lista-de-clases-dentro-de-un-paquete-en-java","status":"publish","type":"post","link":"https:\/\/blogs.ua.es\/miguelon\/2012\/11\/conseguir-la-lista-de-clases-dentro-de-un-paquete-en-java\/","title":{"rendered":"Conseguir la lista de clases dentro de un paquete en Java"},"content":{"rendered":"<p>Estos d\u00edas me he estado peleando con Java para conseguir una cosa. Resulta que en JavaVis (una herramienta para procesamiento de visi\u00f3n artificial desarrollada por nuestro grupo de investigaci\u00f3n) tenemos una opci\u00f3n que nos pareci\u00f3 muy buena: si quieres a\u00f1adir un algoritmo a la librer\u00eda, simplemente dicho algoritmo se escribe en una clase que hereda de una clase abstracta y se deja en un determinado directorio. Dicho directorio se encuentra dentro de la estructura de paquetes de la librer\u00eda. Por ejemplo, si el paquete es javavis.jip2d.functions todos los algoritmos forman parte de este paquete.<\/p>\n<p>Esto que tiene de ventaja: podemos cargar de manera din\u00e1mica los algoritmos, no es necesario que el usuario especifique en ning\u00fan sitio que hay una nueva funci\u00f3n o que alguna existente ha cambiado de nombre. Esto simplifica mucho la tarea para el usuario. Pero claro, \u00bfc\u00f3mo cargar de manera din\u00e1mica esas clases? Muy sencillo, usando <em>reflection<\/em>\u00a0Con el m\u00e9todo Class.forName(), pas\u00e1ndole un String con el nombre de la clase, carga de manera din\u00e1mica dicha clase. Lo que hac\u00edamos hasta ahora era buscar dentro del directorio del paquete, por ejemplo, en javavis\/\/jip2d\/\/functions todos los ficheros con extensi\u00f3n .class y luego carg\u00e1bamos con el Class.forName() la clase. Sencillo y eficaz, aunque un poco lento al tener que leer del sistema de ficheros.<\/p>\n<p>Pero esto tiene un problema insalvable: si quieres que tu aplicaci\u00f3n se distribuya como un \u00fanico fichero jar, ya no vas a tener los directorios y entonces ya no vas a poder acceder a esas clases. La soluci\u00f3n es seguir usando reflection, pero obteniendo las clases de un determinado paquete. La clase est\u00e1ndar de Java para reflection no permite hacer esto, por lo que tenemos que descargar una librer\u00eda con nombre, tach\u00e1n!, reflections http:\/\/code.google.com\/p\/reflections\/ A\u00f1adimos esta librer\u00eda a nuestro proyecto o lo incluimos en el classpath y a funcionar. Dejo aqu\u00ed un trozo de c\u00f3digo explicado para poder acceder a las clases dentro de un paquete.<\/p>\n<p>Reflections reflections = new Reflections(&#8220;javavis.jip2d.functions&#8221;); \/\/ Por reflection obtenemos la lista de clases que se encuentran dentro de ese paquete.<br \/>\nClass&lt;? extends JIPFunction&gt; func; \/\/ Todas esas clases heredan de JIPFunction<br \/>\nObject[] funcList = ((HashSet)reflections.getSubTypesOf(JIPFunction.class)).toArray(); \/\/ Se obtiene un array con las clases.<\/p>\n<p>for (int cont=0; cont&lt;funcList.length; cont++) {<br \/>\nfunc = (Class&lt;? extends JIPFunction&gt;)funcList[cont]; \/\/ Se convierte la clase JIPFunction<br \/>\nJIPFunction jf = func.newInstance(); \/\/ Se obtiene una nueva instancia de la clase.<br \/>\nSystem.out.println(func.getName()); \u00a0\/\/ Muestra el nombre de la clase (entero, con todos los paquetes)<br \/>\n}<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Estos d\u00edas me he estado peleando con Java para conseguir una cosa. Resulta que en JavaVis (una herramienta para procesamiento de visi\u00f3n artificial desarrollada por nuestro grupo de investigaci\u00f3n) tenemos una opci\u00f3n que nos pareci\u00f3 muy buena: si quieres a\u00f1adir &hellip; <a href=\"https:\/\/blogs.ua.es\/miguelon\/2012\/11\/conseguir-la-lista-de-clases-dentro-de-un-paquete-en-java\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":342,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[374],"tags":[],"class_list":["post-694","post","type-post","status-publish","format-standard","hentry","category-programacion"],"_links":{"self":[{"href":"https:\/\/blogs.ua.es\/miguelon\/wp-json\/wp\/v2\/posts\/694","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.ua.es\/miguelon\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.ua.es\/miguelon\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.ua.es\/miguelon\/wp-json\/wp\/v2\/users\/342"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.ua.es\/miguelon\/wp-json\/wp\/v2\/comments?post=694"}],"version-history":[{"count":2,"href":"https:\/\/blogs.ua.es\/miguelon\/wp-json\/wp\/v2\/posts\/694\/revisions"}],"predecessor-version":[{"id":696,"href":"https:\/\/blogs.ua.es\/miguelon\/wp-json\/wp\/v2\/posts\/694\/revisions\/696"}],"wp:attachment":[{"href":"https:\/\/blogs.ua.es\/miguelon\/wp-json\/wp\/v2\/media?parent=694"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.ua.es\/miguelon\/wp-json\/wp\/v2\/categories?post=694"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.ua.es\/miguelon\/wp-json\/wp\/v2\/tags?post=694"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}