varios proyecto paquetes encontrado ejemplos desde consola configurar compilar clase cargado archivos java reflection

proyecto - no se ha encontrado o cargado la clase principal java



¿Cómo leo todas las clases de un paquete Java en classpath? (16)

  1. Bill Burke ha escrito un (buen article sobre escaneo de clase) y luego escribió Scannotation .

  2. Hibernate tiene esto ya escrito:

    • org.hibernate.ejb.packaging.Scanner
    • org.hibernate.ejb.packaging.NativeScanner
  3. CDI podría resolver esto, pero no lo sabe, no ha investigado por completo todavía

.

@Inject Instance< MyClass> x; ... x.iterator()

También para anotaciones:

abstract class MyAnnotationQualifier extends AnnotationLiteral<Entity> implements Entity {}

Necesito leer las clases contenidas en un paquete de Java. Esas clases están en classpath. Necesito hacer esta tarea desde un programa Java directamente. ¿Conoces una manera simple de hacer?

List<Class> classes = readClassesFrom("my.package")


Aquí hay otra opción, una ligera modificación a otra respuesta arriba / abajo:

Reflections reflections = new Reflections("com.example.project.package", new SubTypesScanner(false)); Set<Class<? extends Object>> allClasses = reflections.getSubTypesOf(Object.class);


Brent: la razón por la que la asociación es de una sola forma tiene que ver con el hecho de que cualquier clase en cualquier componente de tu CLASSPATH puede declararse en cualquier paquete (excepto para java / javax). Por lo tanto, simplemente no hay un mapeo de TODAS las clases en un "paquete" dado porque nadie sabe ni puede saber. Puede actualizar un archivo jar mañana y eliminar o agregar clases. Es como tratar de obtener una lista de todas las personas llamadas John / Jon / Johan en todos los países del mundo; ninguno de nosotros es omnisciente, por lo que ninguno de nosotros tendrá la respuesta correcta.


Cuando los applets eran un lugar común, uno podía tener una URL en el classpath. Cuando el cargador de clases requería una clase, buscaba todas las ubicaciones en la ruta de clase, incluidos los recursos http. Debido a que puede tener cosas como URL y directorios en el classpath, no hay una manera fácil de obtener una lista definitiva de las clases.

Sin embargo, puedes acercarte bastante. Algunas de las bibliotecas de Spring están haciendo esto ahora. Puede obtener todos los jar en classpath y abrirlos como archivos. A continuación, puede tomar esta lista de archivos y crear una estructura de datos que contenga sus clases.



Esa funcionalidad aún se desconoce sospechosamente de la API de reflexión de Java hasta donde yo sé. Puede obtener un objeto de paquete simplemente haciendo esto:

Package packageObj = Package.getPackage("my.package");

Pero como probablemente habrás notado, eso no te permitirá enumerar las clases en ese paquete. A partir de ahora, debe adoptar un enfoque más orientado al sistema de archivos.

Encontré algunas implementaciones de muestra en this publicación

No estoy 100% seguro de que estos métodos funcionarán cuando tus clases estén enterradas en archivos JAR, pero espero que uno de ellos lo haga por ti.

Estoy de acuerdo con @skaffman ... si tienes otra forma de abordar esto, te recomendaría hacerlo en su lugar.


Java 1.6.0_24:

public static File[] getPackageContent(String packageName) throws IOException{ ArrayList<File> list = new ArrayList<File>(); Enumeration<URL> urls = Thread.currentThread().getContextClassLoader() .getResources(packageName); while (urls.hasMoreElements()) { URL url = urls.nextElement(); File dir = new File(url.getFile()); for (File f : dir.listFiles()) { list.add(f); } } return list.toArray(new File[]{}); }

Esta solución fue probada dentro del entorno EJB .


Lo he implementado, y funciona en la mayoría de los casos. Como es largo, lo puse en un archivo aquí .

La idea es encontrar la ubicación del archivo fuente de clase que está disponible en la mayoría de los casos (una excepción conocida son los archivos de clase JVM, por lo que he probado). Si el código está en un directorio, escanee todos los archivos y solo ubique los archivos de clase. Si el código está en un archivo JAR, escanee todas las entradas.

Este método solo puede usarse cuando:

  1. Tienes una clase que está en el mismo paquete que deseas descubrir. Esta clase se llama SeedClass. Por ejemplo, si desea listar todas las clases en ''java.io'', la clase semilla puede ser java.io.File .

  2. Sus clases están en un directorio o en un archivo JAR que tiene información de archivo de origen (no un archivo de código fuente, sino solo un archivo fuente). Por lo que he probado, funciona casi al 100%, excepto la clase JVM (esas clases vienen con la JVM).

  3. Su programa debe tener permiso para acceder a ProtectionDomain de esas clases. Si su programa se carga localmente, no debería haber ningún problema.

Probé el programa solo para mi uso habitual, por lo que aún puede tener problemas.

Espero que esto ayude.


Podría usar el Proyecto Reflections descrito here

Es bastante completo y fácil de usar.

Breve descripción del sitio web anterior:

Reflections explora su classpath, indexa los metadatos, le permite consultarlo en tiempo de ejecución y puede guardar y recopilar esa información para muchos módulos dentro de su proyecto.

Ejemplo:

Reflections reflections = new Reflections( new ConfigurationBuilder() .setUrls(ClasspathHelper.forJavaClassPath()) ); Set<Class<?>> types = reflections.getTypesAnnotatedWith(Scannable.class);


Puedes probar mi biblioteca FastClasspathScanner . Escanear el classpath no es tan simple como verificar la propiedad java.class.path , y java.class.path recursiva las clases allí, porque hay muchas formas en que se puede especificar el classpath (por ejemplo, puede agregar entradas Class-Path al manifiesto de un jarfile). El uso de Class.forName () realmente inicializa la clase, que puede no ser la que usted desea, etc. FastClasspathScanner maneja estas complejidades por usted.

Para enumerar todas las clases en un paquete, haga lo siguiente:

String packageName = "my.package"; Set<String> classNames = new FastClassPathScanner(packageName) .scan() .getNamesOfAllClasses(); String packageNamePrefix = packageName + "."; for (String className : classNames) { if (className.startsWith(packageNamePrefix) { System.out.println("Found class: " + className); } }

Necesita el control if (className.startsWith(packageNamePrefix) porque si una clase se refiere a otra clase (por ejemplo, como una superclase), y está fuera del prefijo del paquete de la lista blanca my.package , se incluirá en el conjunto devuelto por .getNamesOfAllClasses()


Si tiene Spring en su classpath, entonces lo siguiente lo hará.

Encuentre todas las clases en un paquete anotado con XmlRootElement:

private List<Class> findMyTypes(String basePackage) throws IOException, ClassNotFoundException { ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver); List<Class> candidates = new ArrayList<Class>(); String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + "/" + "**/*.class"; Resource[] resources = resourcePatternResolver.getResources(packageSearchPath); for (Resource resource : resources) { if (resource.isReadable()) { MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource); if (isCandidate(metadataReader)) { candidates.add(Class.forName(metadataReader.getClassMetadata().getClassName())); } } } return candidates; } private String resolveBasePackage(String basePackage) { return ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage)); } private boolean isCandidate(MetadataReader metadataReader) throws ClassNotFoundException { try { Class c = Class.forName(metadataReader.getClassMetadata().getClassName()); if (c.getAnnotation(XmlRootElement.class) != null) { return true; } } catch(Throwable e){ } return false; }


Spring ha implementado una excelente función de búsqueda de classpath en PathMatchingResourcePatternResolver . Si usa classpath* : prefix, puede encontrar todos los recursos, incluidas las clases en una jerarquía determinada, e incluso filtrarlos si lo desea. Luego puede usar los elementos secundarios de AbstractTypeHierarchyTraversingFilter , AnnotationTypeFilter y AssignableTypeFilter para filtrar esos recursos en anotaciones a nivel de clase o en las interfaces que implementan.


Yo uso este, funciona con archivos o archivos jar

public static ArrayList<String>getClassNamesFromPackage(String packageName) throws IOException{ ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); URL packageURL; ArrayList<String> names = new ArrayList<String>();; packageName = packageName.replace(".", "/"); packageURL = classLoader.getResource(packageName); if(packageURL.getProtocol().equals("jar")){ String jarFileName; JarFile jf ; Enumeration<JarEntry> jarEntries; String entryName; // build jar file name, then loop through zipped entries jarFileName = URLDecoder.decode(packageURL.getFile(), "UTF-8"); jarFileName = jarFileName.substring(5,jarFileName.indexOf("!")); System.out.println(">"+jarFileName); jf = new JarFile(jarFileName); jarEntries = jf.entries(); while(jarEntries.hasMoreElements()){ entryName = jarEntries.nextElement().getName(); if(entryName.startsWith(packageName) && entryName.length()>packageName.length()+5){ entryName = entryName.substring(packageName.length(),entryName.lastIndexOf(''.'')); names.add(entryName); } } // loop through files in classpath }else{ URI uri = new URI(packageURL.toString()); File folder = new File(uri.getPath()); // won''t work with path which contains blank (%20) // File folder = new File(packageURL.getFile()); File[] contenuti = folder.listFiles(); String entryName; for(File actual: contenuti){ entryName = actual.getName(); entryName = entryName.substring(0, entryName.lastIndexOf(''.'')); names.add(entryName); } } return names; }


usar maven de dependencia:

groupId: net.sf.extcos artifactId: extcos version: 0.4b

luego usa este código:

ComponentScanner scanner = new ComponentScanner(); Set classes = scanner.getClasses(new ComponentQuery() { @Override protected void query() { select().from("com.leyton").returning(allExtending(DynamicForm.class)); } });


Scannotation y Reflections usan un enfoque de exploración de ruta de clase:

Reflections reflections = new Reflections("my.package"); Set<Class<? extends Object>> classes = reflections.getSubTypesOf(Object.class);

Otro enfoque es utilizar la API de procesamiento de anotación conectable de Java para escribir un procesador de anotación que recogerá todas las clases anotadas en tiempo de compilación y creará el archivo de índice para su uso en tiempo de ejecución. Este mecanismo se implementa en la biblioteca ClassIndex :

Iterable<Class> classes = ClassIndex.getPackageClasses("my.package");


eXtcos parece prometedor. Imagina que quieres encontrar todas las clases que:

  1. Extiende de la clase "Componente" y guárdalo
  2. Están anotados con "MyComponent", y
  3. Están en el paquete "común".

Con eXtcos esto es tan simple como

ClasspathScanner scanner = new ClasspathScanner(); final Set<Class> classStore = new ArraySet<Class>(); Set<Class> classes = scanner.getClasses(new ClassQuery() { protected void query() { select(). from(“common”). andStore(thoseExtending(Component.class).into(classStore)). returning(allAnnotatedWith(MyComponent.class)); } });