2009-11-25 10 views
5

Sto lavorando su un progetto che mi obbliga a generare un java ".class" File in movimento che può essere successivamente compilato sulla JVM. Dopo aver appreso e lavorando con MSIL (Microsoft IL), che è anche un linguaggio di programmazione intermedia pila base, i seguenti sono i problemi che sto affrontando:Generazione .class programma per JVM

  1. Rispetto alla IL (per C# o VB) il bytecode Java in Il file ".class" contiene informazioni in modo strutturato e per quanto ho potuto capire il file, contiene i metadati oltre ai dati del programma, è vero ?? Posso generare lo stesso in un modulo per ogni file di classe ??
  2. E 'obbligatorio per generare il file di classe in binario ??

Mi sono riferito a "Programmazione per Java ™ Virtual Machine di Joshua Engel" ma non ha funzionato come ho già imparato sul set di istruzioni JVm.

Qualcuno può per favore mi aiuti con questo ?? Tutto l'aiuto sarà molto apprezzato. Un esempio per la generazione di un semplice file di classe sarebbe molto utile in quanto non riuscivo ancora a individuare un singolo 1.

+3

Generazione di un file .class è ciò che il compilatore lo fa. Cosa c'è di sbagliato nel generare il codice e compilarlo? O è qualcosa come Reflection.Emit o Dynamic IL generazione in .NET cosa vuoi per Java? – OregonGhost

+0

Il tuo progetto è di scrivere un compilatore java? –

+1

Ya il mio progetto è un po 'come un compilatore, sto usando C# .NET, uno degli scopi principali è generare il file .class (bytecode) in modo dinamico. –

risposta

4

esempio usando il ASM bytecode library convertito per lavorare con .NET utilizzando i IKVM Java-to-.NET compiler:

hello.cs:

using System; 
using System.IO; 
using org.objectweb.asm; 

namespace test.helloWorld 
{ 
    public class helloDump 
    { 

     public static byte[] dump() 
     { 

      ClassWriter cw = new ClassWriter(0); 
      MethodVisitor mv; 

      cw.visit(Opcodes.__Fields.V1_6, Opcodes.__Fields.ACC_PUBLIC + Opcodes.__Fields.ACC_SUPER, "hello", null, "java/lang/Object", null); 

      mv = cw.visitMethod(Opcodes.__Fields.ACC_PUBLIC, "<init>", "()V", null, null); 
      mv.visitCode(); 
      mv.visitVarInsn(Opcodes.__Fields.ALOAD, 0); 
      mv.visitMethodInsn(Opcodes.__Fields.INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); 
      mv.visitInsn(Opcodes.__Fields.RETURN); 
      mv.visitMaxs(1, 1); 
      mv.visitEnd(); 

      mv = cw.visitMethod(Opcodes.__Fields.ACC_PUBLIC + Opcodes.__Fields.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null); 
      mv.visitCode(); 
      mv.visitFieldInsn(Opcodes.__Fields.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); 
      mv.visitLdcInsn("Hello World!"); 
      mv.visitMethodInsn(Opcodes.__Fields.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); 
      mv.visitInsn(Opcodes.__Fields.RETURN); 
      mv.visitMaxs(2, 1); 
      mv.visitEnd(); 

      cw.visitEnd(); 

      return cw.toByteArray(); 
     } 

     public static void Main(string[] args) 
     { 
      FileStream helloWorldFile = new FileStream("hello.class", FileMode.Create); 
      byte[] helloWorldClass = dump(); 
      helloWorldFile.Seek(0, SeekOrigin.Begin); 
      helloWorldFile.Write(helloWorldClass, 0, helloWorldClass.Length); 
     } 
    } 
} 

comandi:

$ ikvmc -out:org.objectweb.asm.dll -target:library -version:3.2.0.0 asm-3.2.jar 
$ mcs -r:org.objectweb.asm.dll hello.cs 
$ mono hello.exe 
$ ls hello.class 
$ java hello 
+0

Questo è tutto ciò che stavo cercando, thx stobor yt again ... thnx a ton –

0

Hai guardato BCEL?

http://en.wikipedia.org/wiki/Byte_Code_Engineering_Library

E 'bundle con JRE ora.

+0

ya, l'ho visto ma non risolve il mio scopo. Anche se potrebbe essere che non ho molto perché il mio problema è di generare il bytecode da solo (dalla mia applicazione) e non da una seconda applicazione. –

0

Salvare quanto segue in Simple.java e fare javac Simple.java dalla riga di comando (ammesso che abbiate installato il JDK)

public class SimpleJava { 
    public static main(String[] args) { 
    System.out.println("Big Sorry, couldn't stop myself ;-)"); 
    } 
} 

Questo è almeno un modo standard per generare un file di classe semplice;)

+0

Thnx Andreas, ma il problema sta generando il file di classe me stesso non dal comando javac in JVM –

+0

(questa risposta non era molto seria;)) –

0

risposta seria .

Vorrei generare automaticamente il codice Java e utilizzare il compilatore Java per generare il file di classe. Questo aspetto è molto più facile che combattere BCEL. Almeno perché è più facile codificare un algoritmo in una lingua "più alta" rispetto a Java Byte Code.

Qualsiasi altro linguaggio di programmazione che produce codice byte andrà bene, ma credo che Java sia uno degli approcci più facili.

E venendo alle vostre domande,

(1) Sì, alcuni metadati è piuttosto statica. Wikipedia ha una buona panoramica di class file format

(2) Sì, il file di classe è 'binario'. Non v'è alcun alfanumerico lingua (come assembler) per Java bytecode (almeno io non ho sentito parlare di un tale strumento, javap può stampare bytecode leggibile ma non c'è modo di tornare indietro)

Modifica

Ancora difficile da indovinare, ciò che si vuole veramente fare, ma nel caso in cui si desideri scrivere un file di classe attorno a un'espressione aritmetica in grado di valutare l'espressione aritmetica in una macchina virtuale java, è possibile iniziare con la creazione di un file di classe modello.

In tal caso, codificherei questo "valutatore" in Java e testarlo finché non valuterà tutti gli input validi.Userei un campo privato per contenere l'espressione, inizializzata con un'espressione fittizia.

Il file di classe del mio valutatore codificato Java sarebbe un modello perfetto per la generazione di classi 'dinamica' - Dovevo solo scoprire come 'sostituire' l'espressione fittizia con uno reale, ricreare un classfile valido (potresti avere per regolare alcuni puntatori a causa delle diverse lunghezze delle stringhe) e dovrebbe funzionare.

Anche se questa ipotesi è del tutto sbagliato, può servire come caso di studio e può aiutare nel vostro cammino :)

+0

Um ... La mia applicazione consente all'utente di digitare istruzioni in testo normale, convertendo questo in sintassi java, questo non richiederà troppo sovraccarico dato che questo codice java dovrebbe essere compilato ed eseguito su JVM ?? –

+0

Queste affermazioni, qual è il linguaggio di programmazione da cui provengono? E ho pensato che il tuo file di classe fosse progettato per funzionare su una jvm lo stesso? –

+0

Non provengono da alcuna lingua di programmazione, solo testo in inglese! –

2

Si consiglia di guardare in biblioteca ASM bytecode. È piuttosto popolare Molte lingue JVM lo usano: Clojure, Groovy, Jython, JRuby.

Ma sono d'accordo con gli altri postsers che può essere più semplice per generare il sorgente Java e compilarlo con javac per ottenere il vostro file .class. Dipende molto da quello che devi fare.

+0

dovrò pensare a questo, immagino, thnx –