2009-06-13 6 views
3

Ich wollte zu meiner jdk6\jre\lib\security\java.policy Datei ein Verbot hinzufügen, um einige Klassen zu erstellen, die von appengine auf die schwarze Liste gesetzt werden. Zum Beispiel möchte ich, dass mein lokaler jvm eine Ausnahme auslöst, wenn die Anwendung versucht, javax.naming.NamingException zu instanziieren.Kann ich den Zugriff auf eine jvm-Klasse verweigern, indem ich die java.policy-Datei konfiguriere?

Es ist möglich?

Ich werde versuchen, mein spezifisches Problem hier zu erklären. Google bietet einen Service (GAE-google app engine) an, der einige Einschränkungen hinsichtlich der Verwendung von Klassen aufweist. Zum Beispiel werden JNDI-Klassen, die sich im Paket javax.naming befinden, nicht instanziiert. Sie bieten auch einen Test-Server an, der verwendet werden kann, um diese Anwendung auf meinem Computer zu testen, aber dieser Server lässt solche Klassen zu und kann den Code analysieren. Sie stellen fest, dass Sie eine Blacklist-Klasse nur verwendet haben, nachdem Sie Ihre Anwendung auf Google hochgeladen haben. Ich habe darüber nachgedacht, ob eine solche Klassen-Blacklist-Durchsetzung auf dem Entwicklungsjvm nicht möglich ist. Sonst denke ich, dass dies einfach wäre, sie könnten bereits eine solche Richtliniendatei bereitstellen.

+2

Bevorzugen Sie Whitelists zu Blacklists. –

Antwort

6

Sie könnten eine kleine Loader-Anwendung schreiben, die eine new, custom classloader erstellt. Ihre Anwendungsklassen könnten dann mit diesem Classloader geladen werden.

In dem benutzerdefinierten Classloader können Sie dann ClassNotFoundException auslösen, wenn Ihre Anwendung versucht, auf eine Klasse zuzugreifen, die Sie in der schwarzen Liste speichern möchten.

Sie müssen die Methode load() überladen. Diese Methode ist dafür verantwortlich, die Ausnahme in Klassen mit der schwarzen Liste zu werfen oder an den übergeordneten Classloader zu delegieren, wenn die Klasse zulässig ist. Eine Beispielimplementierung:

public Class loadClass(String name) throws ClassNotFoundException { 
    if(name.equals("javax.lang.ClassIDontLike")){ 
     throw new ClassNotFoundException("I'm sorry, Dave. I'm afraid I can't do that."); 
    } 
    return super.loadClass(name, false); 
} 

(Natürlich kann eine echte Implementierung sein Weg anspruchsvoller als diese)

Da die Klassen Ihrer Anwendung werden über diese Classloader geladen, und Sie delegieren nur die loadclass () Aufrufen des übergeordneten Classloaders, wenn Sie möchten, können Sie alle Klassen, die Sie benötigen, in die Blacklist aufnehmen.

Ich bin mir ziemlich sicher, dass dies die Methode ist, mit der Google Klassen auf ihrem Server in die Blacklist aufnimmt. Sie laden jede App in einen bestimmten Classloader. Dies ähnelt auch der Art und Weise, wie Tomcat die verschiedenen Web-Anwendungen isoliert.

+1

Ich glaube, Class.forName() kann einen benutzerdefinierten Classloader umgehen und direkt zum Laden von Boot-/Systemklassen wechseln. Ich denke, es gibt Befehlszeilenargumente, um sogar den Boot-Classloader zu ersetzen, könnte auch dort aussehen – basszero

+0

Sie haben Recht, Class.forName() würde den Boot/System Classloader verwenden. Dies ist eine häufige Ursache für Trauer bei der Verwendung von Eclipse. –

0

Die Java Dokumentation listet alle möglichen politischen Berechtigungen hier: http://java.sun.com/javase/6/docs/technotes/guides/security/permissions.html

Klasse creation/Laden nicht erwähnt wird, so dass ich glaube, dass Sie dies mit einer Politik nicht durchsetzen können.

Warum möchten Sie auf jeden Fall eine Ausnahme auslösen, wenn eine Ausnahmeklasse geladen wird? Vielleicht könnten Sie Ihr Problem erklären, dann könnte jemand eine Lösung vorschlagen.

Edit:

Eine Möglichkeit Laden bestimmter Klassen zu verhindern, wäre sie von der JRE-Installation zu entfernen. Die meisten Systemklassen sind in rt.jar in Ihrer JDK/JRE-Installation enthalten. Sie sollten es mit jedem ZIP-Tool ändern können.

Erstellen Sie einfach eine spezielle Installation Ihrer JRE und ändern Sie ihre rt.jar. Das ist ein hässlicher Hack, aber sollte für Testzwecke in Ordnung sein ...

1

Würden Sie beim Testen Ihres Programms lieber keine Kompilierungsfehler als Laufzeitfehler erhalten?Sie könnten Ihre IDE oder Ihren Compiler so konfigurieren, dass Sie gewarnt werden, wenn eine unerwünschte Klasse instanziiert wird. Ich weiß, dass AspectJ einige nette Eigenschaften dafür hat: Sie können Kompilierungswarnungen/-fehler auf Join-Punkten definieren und Feedback in z.B. Finsternis. Um dies in Eclipse zu verwenden, installieren Sie einfach das AspectJ-Plugin und schreiben einen geeigneten Aspekt. Um die Fehler beim Kompilieren von einer Befehlszeile oder einem Skript zu bekommen, müssten Sie tatsächlich den AspectJ-Compiler verwenden, aber ich bezweifle, dass Sie das brauchen würden.