Политика безопасности Java Sandboxing - PullRequest
0 голосов
/ 03 июля 2018

Я следую этому уроку Урок о том, как добиться песочницы при использовании плагинов.

Это мой основной класс, где я загружаю класс из файла 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.

...