我正在按照本教程tutorial进行操作,了解如何在使用插件时实现沙箱操作。
这是我的主要课程,我从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);
}
这是我的插件类加载器:
导入java.net.URL; 导入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错误。