/
FileClassLoader.java
103 lines (83 loc) · 3.18 KB
/
FileClassLoader.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package com.bgsoftware.superiorskyblock.core.io;
import com.google.common.io.ByteStreams;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.CodeSigner;
import java.security.CodeSource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
public class FileClassLoader extends URLClassLoader {
private final Map<String, Class<?>> classes = new ConcurrentHashMap<>();
private final JarFile jar;
private final Manifest manifest;
private final URL url;
public FileClassLoader(File file, ClassLoader pluginClassLoader) throws IOException {
super(new URL[]{file.toURI().toURL()}, pluginClassLoader);
this.jar = new JarFile(file);
this.manifest = jar.getManifest();
this.url = file.toURI().toURL();
}
@Nullable
@Override
public URL getResource(String name) {
URL url = findResource(name);
return url == null ? super.getResource(name) : url;
}
@Override
public void close() throws IOException {
try {
super.close();
} finally {
jar.close();
}
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> result = classes.get(name);
if (result == null) {
String path = name.replace('.', '/').concat(".class");
JarEntry entry = jar.getJarEntry(path);
if (entry != null) {
byte[] classBytes;
try (InputStream is = jar.getInputStream(entry)) {
//noinspection UnstableApiUsage
classBytes = ByteStreams.toByteArray(is);
} catch (IOException ex) {
throw new ClassNotFoundException(name, ex);
}
int dot = name.lastIndexOf('.');
if (dot != -1) {
String pkgName = name.substring(0, dot);
if (getPackage(pkgName) == null) {
try {
if (manifest != null) {
definePackage(pkgName, manifest, url);
} else {
definePackage(pkgName, null, null, null, null, null, null, null);
}
} catch (IllegalArgumentException ex) {
if (getPackage(pkgName) == null) {
throw new IllegalStateException("Cannot find package " + pkgName);
}
}
}
}
CodeSigner[] signers = entry.getCodeSigners();
CodeSource source = new CodeSource(url, signers);
result = defineClass(name, classBytes, 0, classBytes.length, source);
}
if (result == null) {
result = super.findClass(name);
}
classes.put(name, result);
}
return result;
}
}