programing

Java 클래스가 로드되는 위치를 찾습니다.

nicescript 2022. 8. 16. 22:17
반응형

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

존의 버전은 오브젝트가 다른 오브젝트에 접속되어 있을 때 실패합니다.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<?> 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();

이 비슷한 질문을 보세요. 동일한 클래스를 검색하기 위한 도구입니다.

커스텀 클래스 로더(db 또는 ldap에서 로드)가 있는 것이 가장 큰 장애라고 생각합니다.

간단한 방법:

System.out.println(java.lang).String.class.getResource(String.class.getSimpleName()+.class");

출력 예:

jar: 파일:/D:/Java/jdk1.8/jre/lib/rt.jar!/java/lang/String.class

또는

문자열 obj = "syslog test"; System.out.println(obj.getClass().getResource(obj.getClass().getSimpleName()+.class");

출력 예:

jar: 파일:/D:/Java/jdk1.8/jre/lib/rt.jar!/java/lang/String.class

이 접근방식은 파일과 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

반응형