2017-02-14 10 views
0

바이트 배열에로드 된 jar 파일에서 클래스의 인스턴스를 만들려고합니다.

나는 두 개의 인수를 수신하고 있습니다 : 필요한 클래스와 jar 파일을 나타냅니다
1 바이트 []
2. 자격을 갖춘 클래스 이름

내가 로컬로 테스트하고있어이를 것으로 예상하지만로 작동 나는 업로드 할 때 동일한 정규화 된 클래스 이름을 가진 동일한 jar 파일 (Tomcat 서버에 배포 된 프런트 엔드에 대한 AngularJS 및 Back MVC로 구현 된 웹 응용 프로그램 사용) :

java.lang.ClassNotFoundException

디버깅을 할 때 ou 그 클래스 로더가 올바르게 호출되었지만 jar에서 하나의 클래스가로드되지 않습니다.

그 차이점이 무엇인지 알 수 있거나 다른 방법으로이 기능을 구현할 수 있다면 고맙겠습니다.


클래스를로드하고 그것의 인스턴스를 반환하는 방법
바이트 배열로 표시된 jar 파일에서 클래스를로드하는 데 문제가 발생했습니다.

public class ByteClassLoader extends ClassLoader { 
    private static final Logger LOGGER = Logger.getLogger(ByteClassLoader.class); 
    private final byte[] jarBytes; 
    private final Set<String> names; 

    public ByteClassLoader(byte[] jarBytes) throws IOException { 
     this.jarBytes = jarBytes; 
     this.names = loadNames(jarBytes); 
    } 

    private Set<String> loadNames(byte[] jarBytes) throws IOException { 
     Set<String> set = new HashSet<>(); 
     try (ZipInputStream jis = new ZipInputStream(new ByteArrayInputStream(jarBytes))) { 
      ZipEntry entry; 
      while ((entry = jis.getNextEntry()) != null) { 
       set.add(entry.getName()); 
      } 
     } 
     return Collections.unmodifiableSet(set); 
    } 

    @Override 
    public InputStream getResourceAsStream(String resourceName) { 
     if (!names.contains(resourceName)) { 
      return null; 
     } 
     boolean found = false; 
     ZipInputStream zipInputStream = null; 
     try { 
      zipInputStream = new ZipInputStream(new ByteArrayInputStream(jarBytes)); 
      ZipEntry entry; 
      while ((entry = zipInputStream.getNextEntry()) != null) { 
       if (entry.getName().equals(resourceName)) { 
        found = true; 
        return zipInputStream; 
       } 
      } 
     } catch (IOException e) { 
      LOGGER.error("ByteClassLoader threw exception while reading jar byte stream for resource: "+resourceName, e); 
      e.printStackTrace(); 
     } finally { 
      if (zipInputStream != null && !found) { 
       try { 
        zipInputStream.close(); 
       } catch (IOException e) { 
        LOGGER.error("ByteClassLoader threw exception while closing jar byte stream for resource: "+resourceName, e); 
        e.printStackTrace(); 
       } 
      } 
     } 
     return null; 
    } } 

답변

0

문제를로드 할 데 필요한 클래스가 범위이었다이었다 :

public static <T> T getInstanceOfLoadedClass(byte[] jarFileBytes, String qualifiedClassName) throws ClassFromJarInstantiationException { 
    LOGGER.info("Getting instance of class from loaded jar file. Class name: " + qualifiedClassName); 
    try { 
     return (T) Class.forName(qualifiedClassName, true, new ByteClassLoader(jarFileBytes)).newInstance(); 
    } catch (InstantiationException | IllegalAccessException | IOException | ClassNotFoundException | NoSuchFieldException e) { 
     LOGGER.error("Exception was thrown while reading jar file for " + qualifiedClassName + "class.", e); 
     throw new ClassFromJarInstantiationException(e); 
    } 
} 

사용자 정의 ByteClassLoader을 클래스 로더가 테스트되는 동안.
정말 쉽게 놓칠 수 있기 때문에이 문제를 해결하는 데 도움이되기를 바랍니다.