2017-01-27 14 views
1

내 전쟁 코드에 jar 파일 (및 해당 클래스)을 동적으로로드하려고했습니다.ClassCastException Java에서 런타임시 WAR 외부의 JAR 파일에서 클래스를 동적으로로드하는 동안 오류가 발생 했습니까?

import java.io.File; 
import java.net.*; 

public class ObjectFactory { 

    private ClassLoader cl; 

    public ObjectFactory(String jarFilePath) { 

     try { 
      File file= new File(jarFilePath); 
      URL url = file.toURL(); 
      URL[] urls = new URL[]{url}; 
      cl = new URLClassLoader(urls); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 


    } 


    public <T> T getObject(String id){ 
     try { 
      Class cls = cl.loadClass(id); 
      T object =(T)cls.newInstance(); 

      return object; 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

} 

내가 오리 인터페이스가 :

public interface Duck { 
    public String quack(String arg); 
} 

을 그리고 내가 런타임에 원하는 오리를 얻기 위해 서비스 클래스를 만들었습니다

내가 같은 내 객체 팩토리 클래스를 작성한 이렇게하려면 :

public class DuckServiceClass { 

    public static Duck getDuck(){ 
     try { 
     String jarFilePath="\path\to\my\external_jar.jar" 
     ObjectFactory of = new ObjectFactory(jarFilePath); 
     Duck d1=of.getObject("implementationOfDuck.RobotDuck");  
     return d1; 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

} 

My Jar에는 Duck 인터페이스 사본이 있고 Duck :의 다양한 구현이 있습니다. 예를 RobotDuck 클래스 6,:

package implementationOfDuck; 
import Duck; 

public class RobotDuck implements Duck { 

    @Override 
    public String quack(String arg) { 
     return "Q U A N C K!!!" +arg; 
    } 

} 

이 서비스 클래스는 main 메소드에 모두 잘 작동 :

java.lang.ClassCastException: implementationOfDuck.RobotDuck cannot be cast to Duck 
을 : 내 JSP 페이지에서이 ServiceClass 방법을 참조하면

public class WebAppTest { 

    public static void main(String[] args) { 
     Duck d1 =DuckServiceClass.getDuck(); 
     System.out.println(d1.getName()+">"+d1.quack("Hello")); 
    } 

} 

그러나 그것은 나에게 준다

내 JSP 페이지는 다음과 같습니다.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" 
    pageEncoding="ISO-8859-1"%> 
<%@ page import="Duck" %> 
<%@ page import="DuckServiceClass" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>Duck-O-Gram</title> 
</head> 
<body> 
<% 
Duck d1=DuckServiceClass.getDuck(); 
%> 
<h1><%=d1.quack("Hello")%></h1> 
</body> 
</html> 

웹 앱에서이 문제를 해결하는 방법을 안내해 줄 수 있습니까?

+0

이것은 일반적으로 'Duck'이 다른 클래스 로더에 의해 두 번로드되었음을 의미합니다. –

+0

@ JimGarrison 두 번로드하지 않는 것 같습니다. jar가 동적으로로드되기 때문에. 또한 동일한 서비스 메소드가 기본 메소드에서 잘 작동합니다. – user3769778

+0

미안 @ 짐 가슨 당신이 말한 것을 이해하지 못했습니다. 당신 말이 맞았습니다. Beckyang 솔루션, 기반이 나를 위해 일한 당신의 제안. – user3769778

답변

1

@ JimGarrison이 말한 것처럼 Duck은 webapp 클래스 로더로로드되고 URLClassLoader은 두 번로드됩니다.

URLClassLoader의 생성자에있는 상위 클래스 로더를 지정하면 문제를 해결할 수 있습니다. cl은 먼저 부모 클래스 로더를 사용하여 클래스/리소스를 검색 한 다음 지정된 URL에서 클래스/리소스를로드합니다. Duck이 이미 webapp 클래스 로더에 의해로드되었으므로 Duck.class 안에 external_jar.jar이 다시로드되지 않습니다.

public ObjectFactory(String jarFilePath) { 
    try { 
     File file= new File(jarFilePath); 
     URL url = file.toURL(); 
     URL[] urls = new URL[]{url}; 
     cl = new URLClassLoader(urls, getClass().getClassLoader()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
+0

제 문제를 해결해 주신 고맙습니다. :) 클래스 로딩을 연구해야합니다. 이제 배포하지 않고 코드를 변경할 수있게되어서 고맙습니다. 큰!!! – user3769778