누구나 Java 클래스 로더가 실제로 클래스를로드하는 위치를 프로그래밍 방식으로 찾는 방법을 알고 있습니까?
나는 종종 클래스 패스가 길어지고 수동 검색이 실제로 옵션이 아닌 큰 프로젝트에서 일합니다. 최근 에 클래스 로더가 클래스 경로에 있었기 때문에 클래스 로더가 잘못된 버전의 클래스를로드하는 데 문제 가있었습니다 .
그렇다면 실제 클래스 파일의 디스크 위치를 클래스 로더에게 알려주려면 어떻게해야합니까?
편집 : 버전 불일치 (또는 다른 것)로 인해 클래스 로더가 실제로 클래스를로드하지 못하면 어쨌든 읽기 전에 어떤 파일을 읽으려고합니까?
답변
예를 들면 다음과 같습니다.
package foo;
public class Test
{
public static void main(String[] args)
{
ClassLoader loader = Test.class.getClassLoader();
System.out.println(loader.getResource("foo/Test.class"));
}
}
이것은 인쇄되었습니다 :
file:/C:/Users/Jon/Test/foo/Test.class
답변
소스를 조작하지 않고 클래스가로드되는 위치를 찾는 또 다른 방법은 다음 옵션을 사용하여 Java VM을 시작하는 것입니다. -verbose:class
답변
getClass().getProtectionDomain().getCodeSource().getLocation();
답변
이것이 우리가 사용하는 것입니다.
public static String getClassResource(Class<?> klass) {
return klass.getClassLoader().getResource(
klass.getName().replace('.', '/') + ".class").toString();
}
이것은 ClassLoader 구현에 따라 작동합니다.
getClass().getProtectionDomain().getCodeSource().getLocation()
답변
객체가 다음과 같은 경우 Jon의 버전이 실패합니다. ClassLoader
가 null
Boot에 의해로드 된 것으로 보이는 것처럼 가 등록ClassLoader
.
이 방법은 해당 문제를 처리합니다.
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";
}
답변
첫 번째 줄만 편집 : Main
.class
Class<?> c = Main.class;
String path = c.getResource(c.getSimpleName() + ".class").getPath().replace(c.getSimpleName() + ".class", "");
System.out.println(path);
산출:
/C:/Users/Test/bin/
어쩌면 나쁜 스타일이지만 잘 작동합니다!
답변
일반적으로 하드 코딩을 사용하지 않습니다. 먼저 className을 가져온 다음 ClassLoader를 사용하여 클래스 URL을 가져올 수 있습니다.
String className = MyClass.class.getName().replace(".", "/")+".class";
URL classUrl = MyClass.class.getClassLoader().getResource(className);
String fullPath = classUrl==null ? null : classUrl.getPath();