2010-06-22 27 views
5

voglio importare una classe che ho già scritto in una cartella esterna, ad esempio: La mia classe Example.java che si trova nella c:\class\Example.java al mio script come usandoscript java: importare una classe da un file esterno

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

o

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

questo è in uno script per ScriptEngine rinoceronte
come posso farlo ???

+1

Qualsiasi motivo non è possibile utilizzare il classpath? –

+0

Vuoi importare una classe Java in JavaScript che verrà eseguita usando Rhino? O vuoi importare una classe JavaScript in Java usando Rhino? –

+0

Voglio importare una classe Java in un file JavaScript che verrà eseguito utilizzando Rhino :) questo è –

risposta

5

Capisco che si desidera:

  1. compilare un file sorgente Java
  2. Caricare il codice compilato
  3. Utilizzare la classe risultante in qualche JavaScript

Il pacchetto javax.tools fornisce una meccanismo per la compilazione del codice, anche se non si esegue in un JDK, ToolProvider.getSystemJavaCompiler() restituirà null e si dovrà fare affidamento su e altri meccanismi di compilazione (invocazione di un compilatore esterno; incorporare il compilatore Eclipse; eccetera.).

bytecode Java (binari .class) possono essere caricati in fase di esecuzione tramite ClassLoader s.

Affinché le classi caricate siano visibili al motore di scripting, è necessario fornirle tramite il costruttore ScriptEngineManager(ClassLoader).


EDIT: sulla base dei requisiti

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

Questo script solo richiama la riflessione API Java per caricare e istanziare una classe HelloWorld.class dalla C:\foo\bin directory:

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(); 
} 

ci sono più modi eleganti per farlo, ne sono sicuro.

+0

Immagina di avere un'applicazione e che non voglio cambiare, tutto quello che posso cambiare è il file di script che viene caricato nell'applicazione. Quindi, se voglio fare qualcosa, non posso farlo nel codice Java dell'applicazione, ma solo nel file di script, quindi, voglio importare una classe che è esterna al mio progetto, che è compilato e localizzato in il mio disco rigido. Spero di essere più esplicito: s thnx un sacco –

0

Se ho capito bene, ciò che stai effettivamente cercando di fare è caricare le classi Java in modo che tu possa (presumibilmente) creare istanze, eccetera. Il termine per questo è il caricamento dinamico non importato.

Java consente di caricare dinamicamente i file bytecode (*.class) utilizzando il metodo ClassLoader.loadClass(String). Ci sono molte risorse su questo argomento; per esempio. la pagina "Class Loading" dell'esercitazione JNDI. Preparati a passare un po 'di tempo a capire questo argomento. In particolare, poiché stai provando a caricare una classe che non si trova nel normale classpath della tua applicazione, dovrai creare un nuovo classloader per farlo. I Javadoc per la classe java.lang.ClassLoader sono here.

Il codice sorgente Java non può essere caricato direttamente, ma deve prima essere compilato utilizzando un compilatore Java. Se si sta utilizzando un'installazione JDK moderna, è possibile chiamare il compilatore Java in fase di esecuzione. Ma un'installazione di JRE non include un compilatore Java. Se la piattaforma dispone di un compilatore Java disponibile in fase di runtime, è possibile accedervi tramite il metodo statico getSystemJavaCompiler() della classe ToolProvider. Ancora una volta, chiamare il compilatore Java da un'applicazione Java in esecuzione è complicato.

+0

Thnx per la risposta, Quello che voglio fare, è quello di aggiungere una classe, ad esempio MyClass.java che ho compilato su MyClass.class quindi mi piacerebbe importare MyClass nel mio disco rigido, non nei pacchetti del mio progetto, e questo, all'interno di un file di script: ad esempio: importClass ("D: \\ SVN_KC \\ KP script \\ tronco \\ Protos \\ ScriptEngine \\ \\ Exemple.class "); –

1

Mi chiedevo perché farlo.

Le soluzioni elencate qui funzioneranno. Il problema sta per essere che:

  1. si avrà un messo insieme soluzione con la riflessione che sarà essere difficile da risolvere.
  2. I vostri clienti stanno bene con il codice di patch caricato nel runtime ? Everyplace I ha funzionato a non è.
+0

La cosa da fare è consentire ai clienti di modificare i file di script senza toccare l'applicazione. Penso che usare l'introspezione come è stato detto nel file di script funzionerà molto –