2010-11-25 2 views
1
String CompilePath = "abc.java"; 
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
String classpath = System.getProperty("java.class.path"); 
System.setProperty("java.class.path", classpath + ";" + LocalMachine.home + "WebContent/WEB-INF/lib"); 
int result = compiler.run(null, null, null, CompilePath); 

위의 실행은 벌금을 컴파일에 필요한 모든 jars 이후 JUnit 테스트로 실행될 때 abc.java 파일. 그러나 동일한 코드가 서버로 실행될 때 필요한 jar 파일을 찾지 못합니다. System.getProperty("java.class.path")의 출력은 E:\apache-tomcat-7.0.4\bin\bootstrap.jar;E:\apache-tomcat-7.0.4\bin\tomcat-juli.jar;C:\Program Files\Java\jdk1.6.0_21\lib\tools.jar"lib에 WEB-INF /"를 표시하지 않습니다은 System.getProperty ("java.class.path를")와 포함 항아리는

입니다. 따라서 제 질문은 컴파일러가 WEB-INF/lib 디렉토리에서 jar 파일을 참조하도록 만드는 방법입니까?

+0

어떻게 앱을 패키징 (WAR 생성)하고 있습니까? – CoolBeans

답변

0

java.class.path 시스템 속성을 설정하는 방법은 문제를 묻는 것입니다. 더 나은 방법은 아닙니다. 좀 더 우아한 방법은 -classpath 옵션을 사용하여 사용자 정의 클래스 경로를 전달하는 것입니다. 자세한 내용은 How do I use JDK6 ToolProvider and JavaCompiler with the context classloader?을 참조하십시오.

는 또한이 질문은 유용한 참고 자료가 될 수 있습니다 실제 클래스 경로를 구축으로 Using javax.tools.ToolProvider from a custom classloader?


, 당신은 URLClassLoader에 컨텍스트 클래스 로더를 캐스팅 수 있고 (this answer에서 수행으로) 해당 URL에서 파일을 얻을.

또는 ServletContext을 사용할 수 있습니다. 웹 응용 프로그램 (안 WAR 파일) 전개되고있는 경우 모두 작업을 접근 : 경고

ServletConfig cfg = ...; //obtained in Servlet.init(ServletConfig) method 
ServletContex ctx = cfg.getServletContext(); 
String realWebInfPath = ctx.getRealPath("WEB-INF/lib"); 
//TODO use the realWebInfPath to create a File object and iterate over all JAR files 

: getRealPath(String)하여 전체 클래스 경로를 구축 할 수 있습니다. 확장되지 않으면 운이 없어진 것입니다.

+0

당신이 언급 한 솔루션이 유용 할 지 모르지만, 대신 클래스 경로를 쉽게 통과 할 수있는 배치 스크립트를 실행하는 것이 매우 쉬운 방법이라는 것을 알았습니다. 나는 이것이 어떤 방법으로도 이상적인 방법이 아니라는 것을 알고 있습니다. – brayne

-2

WAR 파일을 작성하는 데 ANT를 사용한다고 가정합니다. WAR에서 WEB-INF/lib 아래에 jar를 포함 시키려면 아래처럼해야합니다. 디렉토리 구조를 수정하여 앱 디렉토리 구조에 맞 춥니 다.

<war warfile="yourApp.war" webxml="WEB-INF/web.xml"> 
      <fileset dir="yourWarDir"> 
       <include name="**/*.jsp"/> 
       <include name="**/include/**"/> 
      </fileset> 
      <include name="WEB-INF/lib/*"/> 
      <include name="WEB-INF/classes/**"/> 

</war> 
+0

웹 응용 프로그램에 JAR 파일을 포함하는 방법에 대한 지침을 묻지 않는다고 생각합니다. –

+0

빌드에 개미를 사용하고 있지 않습니다. 이클립스는 웹 프로젝트에서 모든 것을 처리한다. – brayne

+0

@Neeme Praks - 그의 문제는 앱 패키징에 있습니다. 그는 WEB-INF/lib 폴더에 포함 된 jar 파일을 찾기 위해 서버 클래스 경로에 의존합니다. 그게 당신에게 무엇을 말합니까? – CoolBeans

3

특히 java.class.path에 의존하여 설정할 수 없습니다.

Java는 서블릿 컨테이너가 포함 된 전체 JVM을 시작할 때이 변수를 설정합니다. 많은 다른 목적으로 많은 다른 클래스 로더를 생성하기 때문에 변경되지 않습니다. 그럴 순 없어. 전체 프로세스에 대해 java.class.path의 값은 하나 뿐이지 만 여러 웹 응용 프로그램이있을 수 있으며 실제로 각 웹 응용 프로그램 내에 많은 클래스 로더가있을 수 있습니다.

이러한 종류의 컴파일 작업에 대한 클래스 경로를 전달하고 getRealPath를 사용하여 경로 이름을 구성하려면 사용자 고유의 명시 적 구성 메커니즘이 필요합니다.

+0

이제 classpath를 동적으로 변경하는 것이 이치에 맞지 않는다는 것을 이해합니다. 그러나 서블릿에 의해 참조되는 평범한 오래된 자바 객체가 WEB-INF/lib 디렉토리에있는 모든 jar 파일에 성공적으로 액세스 할 수 있기 때문에이 경로는 기본적으로 클래스 경로에 나타나지 않는 이유는 무엇입니까? – brayne

+0

클래스 패스에는 jar 파일 자체가 포함되어 있기 때문에 jar 파일을 포함하는 디렉토리는 포함되어 있지 않습니다. – bmargulies

+0

명시 적 구성 메커니즘은 어떻게 작동합니까? 나에게 같은 것을 보여줄 수 있니? 고마워. – brayne

2

그래서 내 질문은 컴파일러가 WEB-INF/lib 디렉토리의 jar 파일을 참조하도록 만드는 방법입니까?

웹 응용 프로그램의 WAR이 확장되면 웹 컨테이너에서 제공하는 것과 일치하는 클래스 경로 문자열을 프로그래밍 방식으로 만들 수 있어야합니다. 이것은 웹 컨테이너가 사용하는 효과적인 클래스 검색 경로를 복제하는 문제입니다.

그러나 "클래스 경로"인수를 명시 적으로 또는 시스템 속성을 통해 컴파일러에 전달하는 것은 잘못된 방법이라고 생각합니다. this IBM article에서 다음을 찾았습니다.

  • 컴파일러 라이브러리 클래스를 해결할 수있는에서 클래스 경로 :

    컴파일 자바 소스는 다음과 같은 구성 요소가 필요합니다. 컴파일러 클래스 경로는 일반적으로 시스템 디렉터리와 이전에 컴파일 된 .class 파일 을 포함하는 보관 파일 (JAR 또는 ZIP 파일)의 정렬 된 목록으로 구성된 입니다. 클래스 경로는 복수 소스 및 클래스 JavaFileObject 인스턴스를 관리하고 ClassLoader가 을 JavaFileManager 생성자에 전달한 JavaFileManager로 구현됩니다. ...

그래서 올바른 접근 방식은 단지 관련 클래스 로더 객체를 잡아와 JavaFileManager 생성자에 전달하는 것으로 보인다.

+0

"올바른 접근법은 관련 클래스 로더 객체를 잡고 JavaFileManager 생성자에 전달하는 것입니다." - JavaFileManager가 인터페이스라는 점을 감안할 때, 어떻게하면 "생성자"에 어떤 것을 전달할 수 있는지 알지 못합니다. 이 접근법이 가능한 경우, 설명의 목적으로 코드 샘플을 제공 할 수 있습니까?;-) –

+0

ok, JavaFileManager는 실제로 FileManagerImpl을 읽어야하며 참조 된 develperWorks 기사 (http://www.ibm.com/developerworks/java/library/j-jcomp/index.html)에 나와 있습니다. 이 기사는 지금까지 가장 유용한 것으로 보이고 이미 존재하는 classpath 객체를 사용하는 문제를 근사하게 해결하는 것으로 보인다. –

관련 문제