2010-06-22 16 views
5

ich eine Klasse importiert werden soll, die ich bereits in einem externen Ordner schreiben, zum Beispiel: Meine Klasse Example.java, die wie mitScripting java: importieren Sie eine Klasse aus einer externen Datei

var importedClass = new JavaImporter("c:\\class\\Example.java"); 
in c:\class\Example.java meinen Skript befinden

oder

importClass("c:\\class\\Example.java"); 

ist dies in einem Skript für Script rhino
wie kann ich das tun ???

+1

Warum können Sie den Klassenpfad nicht verwenden? –

+0

Möchten Sie eine Java-Klasse in JavaScript importieren, die mit Rhino ausgeführt wird? Oder möchten Sie eine JavaScript-Klasse in Java mit Rhino importieren? –

+0

Ich möchte eine Java-Klasse in eine JavaScript-Datei importieren, die mit Rhino ausgeführt wird :) das ist es –

Antwort

5

Ich verstehe, dass Sie zu wollen:

  1. Erstellen Sie eine Java-Quelldatei
  2. laden den kompilierten Code
  3. Verwenden Sie die resultierende Klasse in einigen JavaScript

Das javax.tools Paket bietet eine Mechanismus zum Kompilieren von Code, obwohl, wenn Sie nicht in einem JDK laufen, wird ToolProvider.getSystemJavaCompiler()null zurückgeben und Sie müssen sich auf Som verlassen der andere Kompilierungsmechanismus (Aufruf eines externen Compilers; Einbetten des Eclipse-Compilers; etc.).

Java-Bytecode (.class Binaries) kann zur Laufzeit über ClassLoader s geladen werden.

Damit die geladenen Klassen für Ihre Skript-Engine sichtbar sind, müssen Sie sie über den ScriptEngineManager(ClassLoader)-Konstruktor bereitstellen.


EDIT: basierend auf den Anforderungen

public class HelloWorld { 
    public void say() { 
    System.out.println("Hello, World!"); 
    } 
} 

Dieses Skript ruft nur das Java-Reflection-API eine Klasse HelloWorld.class aus dem C:\foo\bin Verzeichnis zu laden und instantiieren:

function classImport() { 
    var location = new java.net.URL('file:/C:/foo/bin/'); 
    var urlArray = java.lang.reflect.Array.newInstance(java.net.URL, 1); 
    urlArray[0] = location; 
    var classLoader = new java.net.URLClassLoader(urlArray); 
    return classLoader.loadClass("HelloWorld"); 
} 

var myClass = classImport(); 

for(var i=0; i<10; i++) { 
    myClass.getConstructor(null).newInstance(null).say(); 
} 

Es gibt mehr elegante Wege, das zu tun, da bin ich mir sicher.

+0

Stellen Sie sich vor, dass ich eine Anwendung habe, die ich nicht ändern möchte. Alles, was ich ändern kann, ist die Skriptdatei, die in die Anwendung geladen wird. Also, wenn ich etwas tun möchte, kann ich es nicht in der Anwendung Java-Code, sondern nur in der Skriptdatei, also, ich möchte eine Klasse importieren, die extern zu meinem Projekt ist, das kompiliert und befindet sich in meine Festplatte. Hoffe, dass ich mehr explicatif bin: s Thnx viel –

0

Wenn ich Sie richtig verstehe, was Sie eigentlich tun möchten, laden Sie Java-Klassen, so dass Sie (vermutlich) Instanzen erstellen können, und so weiter. Der Ausdruck dafür ist dynamisches Laden, das nicht importiert wird.

Java ermöglicht das dynamische Laden von Bytecode-Dateien (*.class) mit der Methode ClassLoader.loadClass(String). Es gibt viele Ressourcen zu diesem Thema; z.B. die Seite "Class Loading" aus dem JNDI-Tutorial. Bereiten Sie sich darauf vor, etwas Zeit mit diesem Thema zu verbringen. Insbesondere, da Sie versuchen, eine Klasse zu laden, die sich nicht im normalen Klassenpfad Ihrer Anwendung befindet, müssen Sie dafür einen neuen Klassenlader erstellen. Die Javadocs für die Klasse java.lang.ClassLoader sind here.

Java-Quellcode kann nicht direkt geladen werden, sondern muss zuerst mit einem Java-Compiler kompiliert werden. Wenn Sie eine moderne JDK-Installation verwenden, können Sie den Java-Compiler zur Laufzeit aufrufen. Eine JRE-Installation enthält jedoch keinen Java-Compiler. Wenn Ihre Plattform zur Laufzeit über einen Java-Compiler verfügt, können Sie über die statische Methode getSystemJavaCompiler() der Klasse ToolProvider darauf zugreifen. Auch hier ist der Aufruf des Java-Compilers innerhalb einer laufenden Java-Anwendung kompliziert.

+0

Thnx für die Antwort, Was ich tun möchte, ist eine Klasse zum Beispiel MyClass.java, die ich hinzufügen kompiliert zu MyClass.class , also möchte ich MyClass importieren, das auf meiner Festplatte ist, nicht in den Paketen meines Projekts, und dies innerhalb einer Skriptdatei: zum Beispiel: importClass ("D: \\ SVN_KC \\ KP \\ Stamm \ Protos \ ScriptEngine \\ Skripts \\ Beispiel.class "); –

1

Ich würde fragen, warum dies tun.

Die hier aufgeführten Lösungen funktionieren. Das Problem wird, dass sein:

  1. Sie erhalten eine zusammengeschustert Lösung mit Reflexion, die zu beheben wird hart sein.
  2. Sind Ihre Kunden in Ordnung mit Patch-Code, der bei geladen wird Runtime? Everyplace, an dem ich gearbeitet habe, ist nicht.
+0

Die Sache zu tun ist, um Kunden zu erlauben, die Skriptdateien zu ändern, ohne die Anwendung zu berühren. Ich denke, dass die Verwendung von Introspektion, wie es in der Skriptdatei gesagt wurde, funktioniert sehr –