Java 클래스가로드 된 위치 찾기 패스가 길어지고 수동 검색이

누구나 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의 버전이 실패합니다. ClassLoadernullBoot에 의해로드 된 것으로 보이는 것처럼 가 등록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();