런타임시 byte [] 배열로 표시된 JAR에서 클래스를로드하려고합니다.
나는 부하에 클래스에 대한 두 가지를 알고
는 "RequiredInterface"나는 자격이 이름을 알고
2. 구현
1. "sample.TestJarLoadingClass"
내가 ClassLoader를 확장해야하는 solution 발견을 하지만 던지기 :런타임시 외부 JAR 클래스를로드하는 중 ClassNotFoundException 발생
Exception in thread "main" java.lang.ClassNotFoundException: sample.TestJarLoadingClass
at java.lang.ClassLoader.findClass(ClassLoader.java:530)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at tasks.Main.main(Main.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
언제든지 클래스를로드하고 싶습니다.
이 상황의 원인은 무엇이며 어떻게 제거 할 수 있습니까?
public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
Path path = Paths.get("src/main/java/tasks/sample.jar");
RequiredInterface requiredInterface = (RequiredInterface) Class.forName("sample.TestJarLoadingClass", true, new ByteClassLoader(Files.readAllBytes(path))).newInstance();
}
사용자 정의 클래스 로더 :
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ByteClassLoader extends ClassLoader {
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) {;
e.printStackTrace();
} finally {
if (zipInputStream != null && !found) {
try {
zipInputStream.close();
} catch (IOException e) {;
e.printStackTrace();
}
}
}
return null;
}
}
RequiredInterface :
public interface RequiredInterface {
String method();
}
JAR 파일의 클래스 :
0,123,516는 어떤 도움을 매우
홈페이지 방법을 평가 당신로드 클래스의 실제 로직을 포함 findClass
메소드를 오버라이드 (override) 모든
첫째 : 제 생각에는
package sample;
public class TestJarLoadingClass implements RequiredInterface {
@Override
public String method() {
return "works!";
}
}
내 컴퓨터에 게시 한 코드를 사용했는데 모두 작동했습니다. 당신은 정확한 예외를 게시 할 수 있겠습니까? 또한 사용중인 경로가 ** 실제로 **로드하려는 클래스가 들어있는 jar를 가리키는 지 확인하십시오. –
그래, 전체 예외 메시지를 게시했습니다. 나는 가능한 모든 "어리석은"실수를 모두 확인했다. 클래스 로딩을 요구하는 클래스가 클래스 로더 범위 내에 있지 않은지 확인하십시오. –
네, 맞습니다. 실수로 인터페이스가있는 jar 대신 클래스를 사용하여 jar에 종속성을 추가했습니다. 죄송합니다 –