poner - setbounds java
Encuentra dónde se carga la clase java (10)
Aquí hay un ejemplo:
package foo;
public class Test
{
public static void main(String[] args)
{
ClassLoader loader = Test.class.getClassLoader();
System.out.println(loader.getResource("foo/Test.class"));
}
}
Esto impreso:
file:/C:/Users/Jon/Test/foo/Test.class
¿Alguien sabe cómo averiguar programáticamente dónde el cargador de clases java realmente carga la clase?
A menudo trabajo en proyectos grandes donde el classpath es muy largo y la búsqueda manual no es realmente una opción. Recientemente tuve un problem donde el cargador de clases estaba cargando una versión incorrecta de una clase porque estaba en el classpath en dos lugares diferentes.
Entonces, ¿cómo puedo hacer que el cargador de clases me diga de dónde viene el archivo de clase real?
Editar: ¿Y si el cargador de clases no carga la clase debido a una discrepancia en la versión (o algo más), de todos modos podríamos averiguar qué archivo está tratando de leer antes de leerlo?
Eche un vistazo a esta pregunta similar. Herramienta para descubrir la misma clase ...
Creo que el obstáculo más relevante es si tienes un cargador de clases personalizado (cargando desde un db o ldap)
Editar solo 1ra línea: Main
.class
Class<?> c = Main.class;
String path = c.getResource(c.getSimpleName() + ".class").getPath().replace(c.getSimpleName() + ".class", "");
System.out.println(path);
Salida:
/C:/Users/Test/bin/
¡Tal vez un mal estilo pero funciona bien!
Este enfoque funciona tanto para archivos como para jar
Class clazz = Class.forName(nameOfClassYouWant);
URL resourceUrl = clazz.getResource("/" + clazz.getCanonicalName().replace(".", "/") + ".class");
InputStream classStream = resourceUrl.openStream(); // load the bytecode, if you wish
Esto es lo que usamos:
public static String getClassResource(Class<?> klass) {
return klass.getClassLoader().getResource(
klass.getName().replace(''.'', ''/'') + ".class").toString();
}
Esto funcionará según la implementación de ClassLoader: getClass().getProtectionDomain().getCodeSource().getLocation()
La versión de Jon falla cuando el ClassLoader
del objeto está registrado como null
que parece implicar que fue cargado por Boot ClassLoader
.
Este método se ocupa de ese problema:
public static String whereFrom(Object o) {
if ( o == null ) {
return null;
}
Class<?> c = o.getClass();
ClassLoader loader = c.getClassLoader();
if ( loader == null ) {
// Try the bootstrap classloader - obtained from the ultimate parent of the System Class Loader.
loader = ClassLoader.getSystemClassLoader();
while ( loader != null && loader.getParent() != null ) {
loader = loader.getParent();
}
}
if (loader != null) {
String name = c.getCanonicalName();
URL resource = loader.getResource(name.replace(".", "/") + ".class");
if ( resource != null ) {
return resource.toString();
}
}
return "Unknown";
}
Otra forma de averiguar dónde se carga una clase (sin manipular la fuente) es iniciar la máquina virtual Java con la opción: -verbose:class
Por lo general, no tenemos qué usar hardcoding. Primero podemos obtener className y luego usar ClassLoader para obtener la URL de la clase.
String className = MyClass.class.getName().replace(".", "/")+".class";
URL classUrl = MyClass.class.getClassLoader().getResource(className);
String fullPath = classUrl==null ? null : classUrl.getPath();
Suponiendo que está trabajando con una clase llamada MyClass
, lo siguiente debería funcionar:
MyClass.class.getClassLoader();
Si puede o no obtener la ubicación en disco del archivo .class depende del mismo cargador de clases. Por ejemplo, si está usando algo como BCEL, una clase determinada puede no tener una representación en disco.
getClass().getProtectionDomain().getCodeSource().getLocation();