Java 클래스가로드되는 위치를 찾으십시오
-
03-07-2019 - |
문제
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과 같은 것을 사용하는 경우 특정 클래스에 온 디스크 표현이 없을 수도 있습니다.