2009-11-25 21 views
5

Tôi đang làm việc trên một dự án yêu cầu tôi tạo tệp java ".class" trên đường đi mà sau này có thể được biên dịch trên JVM. Sau khi học và làm việc với MSIL (Microsoft IL) cũng là một ngôn ngữ lập trình trung gian dựa trên stack, sau đây là những vấn đề tôi đang gặp phải:Tạo tệp .class cho JVM

  1. So với IL (for C# hoặc VB) bytecode java ".class" tập tin chứa thông tin một cách có cấu trúc và theo như tôi có thể hiểu được các tập tin, nó có chứa siêu dữ liệu ngoài các dữ liệu chương trình, là nó đúng ?? Tôi có thể tạo ra giống nhau trong một mẫu biểu mẫu cho mỗi tập tin lớp ??
  2. Bắt buộc phải tạo tệp lớp ở dạng nhị phân?

Tôi đã đề cập đến "Lập trình cho máy ảo Java ™ bởi Joshua Engel" nhưng nó đã không phục vụ mục đích của tôi như tôi đã học về tập lệnh JVm.

Ai đó có thể giúp tôi với điều này không ?? Tất cả sự giúp đỡ sẽ được đánh giá cao. Một ví dụ để tạo một tệp lớp đơn giản sẽ thực sự hữu ích vì tôi không thể tìm được một đơn lẻ nào.

+3

Tạo một file .class là những gì các trình biên dịch làm. Có gì sai khi tạo mã và biên dịch nó? Hoặc là một cái gì đó như Reflection.Emit hoặc Dynamic IL thế hệ trong .NET những gì bạn muốn cho Java? – OregonGhost

+0

Dự án của bạn có phải là trình biên dịch java không? –

+1

Ya dự án của tôi là phần nào giống như một trình biên dịch, tôi đang sử dụng C# .NET, một trong những mục tiêu chính là tạo tệp .class (bytecode) động. –

Trả lời

4

ví dụ sử dụng ASM bytecode library chuyển đổi sang làm việc với .NET sử dụng 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); 
     } 
    } 
} 

lệnh:

$ 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

Đây là smthing tôi đang tìm kiếm, thnx stobor yt một lần nữa ... thnx một tấn –

0

Bạn đã xem BCEL chưa?

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

Nó đi kèm với JRE ngay bây giờ.

+0

ya, tôi đã thấy nó nhưng nó không giải quyết được mục đích của tôi. Mặc dù có thể tôi đã không nhận được nhiều bởi vì vấn đề của tôi là để tạo ra bytecode bản thân mình (bởi ứng dụng của tôi) và không phải bởi một ứng dụng thứ 2. –

0

Save the sau để Simple.java và làm javac Simple.java từ dòng lệnh (giả sử bạn có JDK cài đặt)

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

Đó là ít nhất một cách tiêu chuẩn để tạo ra một tập tin lớp đơn giản;)

+0

Thnx Andreas, nhưng vấn đề là tạo ra tệp lớp n của tôi không phải bởi lệnh javac trong JVM –

+0

(câu trả lời này không thực sự nghiêm trọng;)) –

0

câu trả lời nghiêm trọng .

Tôi muốn tự động tạo mã Java và sử dụng trình biên dịch Java để tạo tệp lớp. Điều này trông dễ dàng hơn rất nhiều sau đó chiến đấu với BCEL. Ít nhất là vì nó dễ dàng hơn để mã hóa một thuật toán trong một ngôn ngữ 'cao hơn' hơn trong Mã Byte Java.

Bất kỳ ngôn ngữ lập trình nào khác tạo mã byte sẽ hoạt động tốt, nhưng tôi đoán Java là một trong những cách tiếp cận dễ nhất.

Và đến với câu hỏi của bạn,

(1) Có, một số siêu dữ liệu khá tĩnh. Wikipedia có tổng quan tốt đẹp về số class file format

(2) Có, tệp lớp là 'nhị phân'. Không có alphanumerical ngôn ngữ (như lắp ráp) cho java bytecode (ít nhất là tôi đã không nghe nói về bất kỳ công cụ như vậy, javap có thể in bytecode có thể đọc được nhưng không có cách nào trở lại)

Sửa

Tuy khó đoán, những gì bạn thực sự muốn làm, nhưng chỉ trong trường hợp, bạn muốn viết một classfile xung quanh một biểu thức số học có thể đánh giá biểu thức số học trong một máy ảo java, sau đó bạn thực sự có thể bắt đầu với việc tạo một tệp lớp mẫu.

Trong trường hợp đó, tôi sẽ viết mã 'bộ đánh giá' này trong Java và kiểm tra nó cho đến khi nó đánh giá tất cả các đầu vào hợp lệ.Tôi muốn sử dụng một trường riêng để giữ biểu thức, được khởi tạo với biểu thức giả.

Tệp lớp của trình đánh giá được mã hóa Java của tôi sẽ là mẫu hoàn hảo cho thế hệ lớp 'động' - tôi chỉ cần tìm hiểu cách 'thay thế' biểu thức giả bằng một thực tế, tạo lại tệp lớp hợp lệ (bạn có thể có để điều chỉnh một số con trỏ vì độ dài chuỗi khác nhau) và nó sẽ hoạt động.

Thậm chí nếu đoán này là hoàn toàn sai, nó có thể đóng vai trò như trường hợp nghiên cứu và có thể giúp bạn trên con đường của bạn :)

+0

Um ... Ứng dụng của tôi cho phép người dùng nhập các câu lệnh dưới dạng văn bản thuần túy, chuyển đổi cú pháp này sang cú pháp java, không phải cuộc gọi này sẽ tốn quá nhiều tiền khi mã java này phải được biên dịch và chạy trên JVM không ?? –

+0

Những phát biểu đó, ngôn ngữ lập trình của chúng là gì? Và tôi nghĩ rằng bạn tập tin lớp học sẽ được thiết kế để chạy trên một jvm anyway? –

+0

Chúng không đến từ bất kỳ ngôn ngữ lập trình nào, chỉ bằng văn bản tiếng Anh đơn giản! –

2

Bạn có thể muốn nhìn vào thư viện ASM bytecode. Nó khá phổ biến. Rất nhiều ngôn ngữ JVM sử dụng nó: Clojure, Groovy, Jython, JRuby.

Nhưng tôi đồng ý với những người đăng bài khác rằng nó có thể đơn giản hơn để tạo nguồn Java và biên dịch nó với javac để lấy tệp .class của bạn. Phụ thuộc rất nhiều vào những gì bạn cần làm.

+0

sẽ phải suy nghĩ về điều này tôi đoán, thnx –

Các vấn đề liên quan