Programing

Java 클래스가로드 된 위치 찾기

lottogame 2020. 5. 26. 07:42
반응형

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/

어쩌면 나쁜 스타일이지만 잘 작동합니다!


이 비슷한 질문을 살펴보십시오. 같은 클래스를 발견하는 도구 ..

가장 관련있는 장애물은 사용자 정의 클래스 로더가있는 경우 (db 또는 ldap에서로드)


일반적으로 하드 코딩을 사용하지 않습니다. 먼저 className을 가져온 다음 ClassLoader를 사용하여 클래스 URL을 가져올 수 있습니다.

        String className = MyClass.class.getName().replace(".", "/")+".class";
        URL classUrl  = MyClass.class.getClassLoader().getResource(className);
        String fullPath = classUrl==null ? null : classUrl.getPath();

이 접근 방식은 파일과 jar 모두에서 작동합니다.

Class clazz = Class.forName(nameOfClassYouWant);

URL resourceUrl = clazz.getResource("/" + clazz.getCanonicalName().replace(".", "/") + ".class");
InputStream classStream = resourceUrl.openStream(); // load the bytecode, if you wish

이라는 클래스를 사용한다고 가정하면 MyClass다음이 작동합니다.

MyClass.class.getClassLoader();

.class 파일의 디스크 위치를 가져올 수 있는지 여부는 클래스 로더 자체에 따라 다릅니다. 예를 들어 BCEL과 같은 것을 사용하는 경우 특정 클래스에는 온 디스크 표현이 없을 수도 있습니다.

참고 URL : https://stackoverflow.com/questions/227486/find-where-java-class-is-loaded-from

반응형