2009-11-25 7 views
5

Ich arbeite an einem Projekt, bei dem ich eine Java-Datei ".class" erstellen muss, die später auf der JVM kompiliert werden kann. Nach dem Lernen und Arbeiten mit MSIL (Microsoft IL), die ebenfalls ein Stapel basierten Zwischen Programmiersprache ist, werden die folgenden Probleme ich bin vor:Generieren von .class-Datei für JVM

  1. Im Vergleich zu der IL (für C# oder VB) der Java-Bytecode in ".class" Datei enthält Informationen in einer strukturierten Art und Weise und soweit ich die Datei verstehen konnte, enthält es die Metadaten abgesehen von den Programmdaten, ist es wahr? Kann ich das selbe in einer Template-Form für jede Klassendatei erzeugen?
  2. Ist es zwingend erforderlich, die Klassendatei binär zu erzeugen ??

Ich habe auf "Programmierung für die Java ™ Virtual Machine von Joshua Engel" verwiesen, aber es hat meinen Zweck nicht erfüllt, da ich bereits über den JVm Befehlssatz gelernt habe.

Kann mir bitte jemand dabei helfen ?? Alle Hilfe wird sehr geschätzt. Ein Beispiel zum Generieren einer einfachen Klassendatei wäre sehr hilfreich, da ich noch keine einzige 1 finden konnte.

+3

eine .class-Datei zu erzeugen ist, was der Compiler tut. Was ist falsch daran, den Code zu generieren und zu kompilieren? Oder ist sowas wie Reflection.Emit oder Dynamic IL Generation in .NET was willst du für Java? – OregonGhost

+0

Ist Ihr Projekt ein Java-Compiler zu schreiben? –

+1

Ya mein Projekt ist etwas wie ein Compiler, ich benutze C# .NET, eines der Hauptziele ist es, die .class-Datei (Bytecode) dynamisch zu generieren. –

Antwort

4

Beispiel für die Verwendung der ASM bytecode library umgewandelt mit .NET arbeiten mit den 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); 
     } 
    } 
} 

Befehle:

$ 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

Das ist smthing ich suchte, thnx stobor yt wieder ... thnx eine Tonne –

0

Haben Sie sich BCEL angesehen?

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

Es ist jetzt mit JRE gebündelt.

+0

ya, ich habe es gesehen, aber es löst meinen Zweck nicht. Allerdings habe ich viel, weil mein Problem ist, den Bytecode selbst zu erzeugen (durch meine Anwendung) und nicht durch eine zweite Anwendung. –

0

Speichern Sie Folgendes in Simple.java und tun javac Simple.java von der Kommandozeile (vorausgesetzt, Sie haben JDK installiert)

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

Das ist zumindest eine Standardmethode eine einfache Klassendatei zu erzeugen;)

+0

Thnx Andreas, aber das Problem ist das Generieren der Klassendatei meine selbst n nicht durch den javac-Befehl in JVM –

+0

(diese Antwort war nicht wirklich ernst;)) –

0

Ernsthafte Antwort .

Ich würde automatisch Java-Code generieren und den Java-Compiler verwenden, um die Klassendatei zu generieren. Das sieht viel einfacher aus, als mit BCEL zu kämpfen. Zumindest, weil es einfacher ist, einen Algorithmus in einer höheren Sprache als in Java Byte Code zu programmieren.

Jede andere Programmiersprache, die Byte-Code erzeugt, wird auch tun, aber ich denke, Java ist einer der einfachsten Ansätze.

Und kommen auf Ihre Fragen,

(1) Ja, einige Metadaten ziemlich statisch ist. Wikipedia hat einen schönen Überblick über die class file format

(2) Ja, die Klassendatei ist "binär". Es gibt keine alphanumerical Sprache (wie Assembler) für Java-Bytecode (zumindest habe ich nicht von einem solchen Werkzeug gehört, kann javap Bytecode lesbar drucken, aber es gibt keinen Weg zurück)

bearbeiten

Noch schwer zu erraten, was Sie wirklich tun wollen, aber nur für den Fall, Sie möchten eine Klassendatei um einen arithmetischen Ausdruck schreiben, der diesen arithmetischen Ausdruck in einer Java Virtual Machine auswerten kann, dann könnten Sie wirklich mit dem Erstellen einer Template-Klassendatei beginnen.

In diesem Fall würde ich diesen 'Evaluator' in Java codieren und testen, bis es alle gültigen Eingaben ausgewertet hat.Ich würde ein privates Feld verwenden, um den Ausdruck zu halten, der mit einem Dummy-Ausdruck initialisiert wurde.

Die Klassendatei meines Java-codierten Evaluators wäre eine perfekte Vorlage für die 'dynamische' Klassengeneration - ich musste nur herausfinden, wie man den Dummy-Ausdruck durch einen echten ersetzt, eine gültige Klassendatei neu erstellen kann einige Zeiger wegen unterschiedlicher Stringlängen anzupassen) und es sollte funktionieren.

Auch wenn diese Vermutung völlig falsch ist, kann es als Fallstudie dienen und können Sie auf Ihrem Weg helfen :)

+0

Um ... Meine Anwendung ermöglicht es dem Benutzer, Anweisungen im Klartext einzugeben, dies in Java-Syntax umwandeln, wird dies nicht zu viel Overhead erfordern, als dann müsste dieser Java-Code kompiliert und auf JVM ausgeführt werden ?? –

+0

Diese Aussagen, aus welcher Programmiersprache stammen sie? Und ich dachte, du bist class-Datei soll entworfen werden, um auf einem jvm sowieso laufen? –

+0

Sie kommen nicht aus einer Programmiersprache, einfach nur aus englischem Text! –

2

Möglicherweise möchten Sie an der ASM Bytecode-Bibliothek suchen. Es ist ziemlich populär. Viele JVM-Sprachen verwenden es: Clojure, Groovy, Jython, JRuby.

Aber ich mit anderen postsers einverstanden, dass es einfacher sein kann, den Java-Quellcode zu generieren und kompilieren es mit javac Ihre .class-Datei zu erhalten. Hängt viel davon ab, was Sie tun müssen.

+0

muss darüber nachdenken, denke ich, thnx –