¿Hay alguna manera de obligar a un cargador de clases a cargar un paquete incluso si ninguna de sus clases se ha cargado?

StackOverflow https://stackoverflow.com/questions/1816730

Pregunta

Digamos que una base de código java tiene un paquete llamado " com.example " ;.

En tiempo de ejecución, podemos obtener este paquete llamando

Package p = Package.getPackage( "com.example" ); //(returns null)

o incluso obtener una lista de todos los paquetes llamando

Packages[] ps = Package.getPackages();

El problema es que si el ClassLoader aún no ha cargado ninguna clase del paquete, no estará disponible para estas llamadas de función. Podemos forzarlo a cargar el paquete al cargar primero una de las clases del paquete, de esta manera:

this.getClass().getClassLoader().loadClass( "com.example.SomeClass" );
Package p = Package.getPackage( "com.example" ); //(returns non-null)

Sin embargo, esto es hacky y requiere conocer de antemano el nombre de alguna clase que pertenece al paquete.

Entonces, la pregunta es: ¿hay alguna forma de obtener una instancia de Package por nombre, independientemente de si ClassLoader ha hecho algo o no? ¿Son precisas mis suposiciones acerca de cómo la carga de clases / paquetes parecen funcionar en esta situación?

¿Fue útil?

Solución

Supongo que necesita esto porque necesita inspeccionar sus anotaciones. De lo contrario, no le interesaría tener una referencia de paquete cuyas operaciones solo están relacionadas con el acceso a las anotaciones. Esto lleva a la suposición de que también tiene un paquete-info.java definido allí con algunas anotaciones.

Si marca java.lang.Package verá que getPackageInfo solo carga la clase de información del paquete como una clase ordinaria.

Tuve el mismo problema y se me ocurrió esta solución.

public static Package getPackage(String packageName) throws ClassNotFoundException {
    Class.forName(packageName+".package-info"); // makes sure package info exist and that the class loader already knows about the package
    return Package.getPackage(packageName);
}

Otros consejos

Alternativamente, podría usar el directorio raíz de la clase como punto de partida y recorrer todos los archivos y subdirectorios * .class. Esto solo funcionaría si sabe de antemano dónde residirán todos sus archivos .class.

La causa de todo esto es que Java tiene una carga de clase dinámica, por lo que las clases se pueden cargar en tiempo de ejecución desde ubicaciones desconocidas en el momento de la compilación o incluso en el momento del inicio. Por lo tanto, el concepto de un paquete es solo un espacio de nombres para las clases cargadas, no un directorio que puede usar para buscarlas.

Me temo que sus suposiciones no son válidas. Los cargadores de clases hacen la contabilidad de paquetes a medida que cargan clases.

Puede pasar un comodín a ClassLoader.getResources y obligarlo a seleccionar las clases en un paquete, que a su vez hará el trabajo.

Puede hacer su propio ClassLoader que llame a definePackage , pero eso no lo ayudará con los cargadores de clases habituales en uso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top