2014-11-07 6 views
1

다른 메소드를 호출하기 위해 프로그램 내에 jar 파일을로드하려고합니다. 클래스를 가지고 있지만 클래스는 시스템 클래스 로더에 종속적 인 URLClassLoader을 사용하여 jar 파일을로드합니다. 예를 들어로드 된 jar 파일이 System.exit()을 수행하면 전체 응용 프로그램의 실행이 완료되고, 현재 실행중인 Java Virtual Machine을 종료합니다. 내 의도는,로드 된 항아리가 마지막으로 이것을 수행하면 전체 응용 프로그램이 아니라 단지 항아리 만 완료한다는 것입니다. 또한 병을 닫아 나중에 필요할 때 다시 시작할 수 있도록하고 싶습니다. 나는 단지에서 필요한 클래스를 인스턴스화하려면 다음 코드를 사용하고 있는데 내 응용 프로그램에서 메소드를 호출 :jar 파일 용 시스템 클래스 로더와 독립적 인 자바 클래스 로더

// Load a class with classloader = new URLClassLoader(libs); 
if(loadclass == null) 
    loadclass = Class.forName(classname, true, classloader); 
// Execute method 
if(met == null) 
{ 
    Constructor constructor; 
    if(params != null && params.length > 0) 
    { 
     constructor = loadclass.getConstructor(new Class[]{Object[].class}); 
     classinstance = constructor.newInstance(new Object[]{params}); 
    } 
    else 
    { 
     constructor = loadclass.getConstructor(null); 
     classinstance = constructor.newInstance(null); 
    } 
    return (Object)Boolean.TRUE; 
} 

// Generic instance 
if(classinstance == null) 
    classinstance = loadclass.newInstance(); 

// Method invocation 
Method method; 
if(params != null) 
{ 
    if(params.length > 1) 
     method = loadclass.getMethod(met, new Class[]{Object[].class}); 
    else 
     method = loadclass.getMethod(met, new Class[]{Object.class}); 
} 
else 
    method = loadclass.getMethod(met); 

method.setAccessible(true); 
Object ret; 
if(params != null) 
{ 
    if(params.length > 1) 
     ret = (Object)method.invoke(classinstance, new Object[]{params}); 
    else 
     ret = (Object)method.invoke(classinstance, params[0]); 
} 
else 
    ret = (Object)method.invoke(classinstance, null); 

return ret; 

URLClassLoader 시스템 클래스 로더에서 분리하는 방법을 모르겠어요. 이 시점에서 어떤 도움을 주셔서 감사합니다!

+1

는'System.exit'이 클래스 로더 관련 일이 아니다. 당신은 그 접근법에서 운이 없을 수도 있습니다. SecurityManager를 살펴보고 종료 시도를 차단할 수 있습니까? – immibis

+0

예. 올바른 방법은 SecurityManager를 사용하는 것입니다. 감사! –

답변

0

System.exit()은 클래스 로더에 관계없이 프로세스를 종료합니다. 시스템 클래스 로더를 버리는 것은 클래스 로더를 연결하지 않음으로써 수행 할 수 있지만 경고해야합니다. 즉, 모든 시스템 클래스가 빈틈없이로드되어야하며 함께 재생되지는 않습니다. 예를 들어, 한 클래스 로더가 만든 문자열과 다른 클래스 로더의 같은 문자가 들어있는 다른 문자열을 비교하면 실패합니다.

System.exit()에 대한 호출이 성공하지 못하도록 보안 관리자를 오류로 구성 할 수 있습니다. 여기

System.exit()

public void exit(int status) { 
    SecurityManager security = System.getSecurityManager(); 
    if (security != null) { 
     security.checkExit(status); 
    } 
    Shutdown.exit(status); 
} 

는 보안 관리자에 security.checkExit 호출하는 코드입니다. 이는 다음과 같이 구현됩니다 :

public void checkExit(int status) { 
    checkPermission(new RuntimePermission("exitVM."+status)); 
} 

사용 권한 exitVM.<number>의 사용에 유의하십시오. 보안 관리자에 대한 자세한 내용은 here을 참조하십시오.

+0

고마워,이게 정말 도움이된다. 지금은 보안 관리자가 내 필요성에 맞는 수정 된 버전을 구현하는 방법을 배우고 있습니다. –

0

Java Agent가 System.exit()을 호출 할 수 있습니다. 다음 article은 Java 에이전트를 사용하여로드 및 삽입 로깅 문에 바이트 코드를 다시 쓰는 방법에 대해 설명합니다. 동일한 접근법을 사용하여 System.exit에 대한 호출을 제거 할 수 있습니다.

관련 문제