문제

Java 클래스 로더가 실제로 클래스를로드하는 위치를 프로그래밍 방식으로 찾는 방법을 아는 사람이 있습니까?

나는 종종 ClassPath가 매우 길어지고 수동 검색이 실제로 옵션이 아닌 큰 프로젝트에서 작업합니다. 나는 최근에 문제 클래스 로더가 클래스가 두 곳의 클래스 경로에 있었기 때문에 클래스의 잘못된 버전을로드하는 곳.

그렇다면 클래스 로더가 어떻게 디스크에서 실제 클래스 파일이 어디에서 나오는지 알려주려면 어떻게해야합니까?

편집하다: 버전 불일치 (또는 다른 것)로 인해 클래스 로더가 실제로 클래스를로드하지 못하면 어쨌든 우리는 그것을 읽기 전에 어떤 파일을 읽으려고하는지 알아낼 수 있습니까?

도움이 되었습니까?

해결책

예는 다음과 같습니다.

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();
}

클래스 로더 구현에 따라 작동합니다.getClass().getProtectionDomain().getCodeSource().getLocation()

Jon의 버전은 객체가있을 때 실패합니다 ClassLoader 등록되어 있습니다 null 부팅에 의해로드되었음을 암시하는 것 같습니다. 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";
}

1 라인 만 편집 : Main.수업

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을 얻은 다음 클래스 로더를 사용하여 클래스 URL을 얻을 수 있습니다.

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

이 접근법은 파일과 항아리 모두에 적합합니다.

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과 같은 것을 사용하는 경우 특정 클래스에 온 디스크 표현이 없을 수도 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top