Я следую этому уроку Урок о том, как добиться песочницы при использовании плагинов.
Это мой основной класс, где я загружаю класс из файла Jar и запускаю интерфейсную функцию:
import java.io.File;
import java.net.URL;
import java.security.Policy;
public class Main {
public static void main(String[] args){
Policy.setPolicy(new SandboxSecurityPolicy());
System.setSecurityManager(new SecurityManager());
try {
File file = new File("JarDummy.jar");
URL urlJar = file.toURI().toURL();
ClassLoader pluginLoader = new PluginClassLoader(urlJar);
Class<?> pluginClass = pluginLoader.loadClass("ZEngine");
IEngine plugin = (IEngine) pluginClass.newInstance();
plugin.build("file.txt");
}catch (Exception e){
e.printStackTrace();
}
}
}
Это мой интерфейс:
public interface IEngine {
void build(String filename);
}
Это мой загрузчик классов плагинов:
import java.net.URL;
import java.net.URLClassLoader;
public class PluginClassLoader extends URLClassLoader {
public PluginClassLoader(URL jarFileUrl) {
super(new URL[] {jarFileUrl});
}
}
И это моя политика, в которой различные разрешения предоставляются, если класс загружается из плагина:
import sun.plugin.security.PluginClassLoader;
import java.security.AllPermission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.security.ProtectionDomain;
public class SandboxSecurityPolicy extends Policy {
@Override
public PermissionCollection getPermissions(ProtectionDomain domain) {
if (isPlugin(domain)) {
return pluginPermissions();
}
else {
return applicationPermissions();
}
}
private boolean isPlugin(ProtectionDomain domain) {
return domain.getClassLoader() instanceof PluginClassLoader;
}
private PermissionCollection pluginPermissions() {
Permissions permissions = new Permissions(); // No permissions
return permissions;
}
private PermissionCollection applicationPermissions() {
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
return permissions;
}
}
Когда я запускаю основной класс и код выполняет plugin.build()
, я получаю исключение stackoverflow со следующей трассировкой:
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
Exception in thread "main" java.lang.StackOverflowError
at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)
at sun.nio.cs.UTF_8.access$200(UTF_8.java:57)
at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:636)
at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)
at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.PrintStream.write(PrintStream.java:526)
at java.io.PrintStream.print(PrintStream.java:669)
at java.io.PrintStream.println(PrintStream.java:806)
at SandboxSecurityPolicy.getPermissions(SandboxSecurityPolicy.java:12)
at java.security.Policy.implies(Policy.java:721)
at java.security.ProtectionDomain.implies(ProtectionDomain.java:285)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:450)
at java.security.AccessController.checkPermission(AccessController.java:884)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1564)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:318)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at SandboxSecurityPolicy.isPlugin(SandboxSecurityPolicy.java:23)
at SandboxSecurityPolicy.getPermissions(SandboxSecurityPolicy.java:13)
Я не уверен, почему instanceOf
создает рекурсию, ведущую к этому переполнению. Я ценю вашу помощь. Спасибо!
ОБНОВЛЕНИЕ: я запускал один и тот же код на другой машине, он работал нормально. Это похоже на ошибку JDK.