我正在开发一个项目,要求我随时生成一个java“.class”文件,以后可以在JVM上编译。在学习并使用MSIL(Microsoft IL)(也是基于堆栈的中间编程语言)之后,我面临以下问题:
我已经提到“由Joshua Engel编写Java™虚拟机程序”,但由于我已经了解了JVm指令集,所以它没有达到我的目的。
有人可以帮帮我吗?所有帮助将受到高度赞赏。 生成简单类文件的示例非常有用,因为我找不到单个1。
答案 0 :(得分:4)
使用ASM bytecode library使用IKVM Java-to-.NET compiler转换为与.NET一起使用的示例:
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);
}
}
}
命令:
$ 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
答案 1 :(得分:2)
您可能需要查看ASM字节码库。它很受欢迎。很多JVM语言都使用它:Clojure,Groovy,Jython,JRuby。
但我同意其他帖子,可能更容易生成Java源代码并使用javac
编译它以获取.class文件。很大程度上取决于你需要做什么。
答案 2 :(得分:0)
答案 3 :(得分:0)
将以下内容保存到Simple.java
并从命令行执行javac Simple.java
(假设您已安装JDK)
public class SimpleJava {
public static main(String[] args) {
System.out.println("Big Sorry, couldn't stop myself ;-)");
}
}
这至少是生成简单类文件的标准方法;)
答案 4 :(得分:0)
认真回答。
我会自动生成Java代码并使用Java编译器生成类文件。这看起来比与BCEL战斗容易得多。至少因为用比Java字节码更高的语言编写算法更容易。
任何其他生成字节代码的编程语言都可以,但我猜Java是最简单的方法之一。
回答你的问题,
(1)是的,一些元数据非常静态。维基百科对class file format
有一个很好的概述(2)是的,类文件是'二进制'。对于java字节码没有 alphanumerical 语言(比如汇编程序)(至少我没有听说过任何这样的工具,javap可以打印字节码可读但是没有办法回来)
修改强>
还是很难猜到,你真的想要做什么,但为了以防万一,你想围绕一个算术表达式编写一个类文件,可以在java虚拟机中评估该算术表达式,那么你真的可以从创建一个模板类文件。
在这种情况下,我会用Java编写这个'评估者'并对其进行测试,直到它评估所有有效输入。我使用私有字段来保存表达式,用虚拟表达式初始化。
我的Java编码求值程序的类文件将是“动态”类生成的完美模板 - 我只需要找出如何用真实表达式“替换”虚拟表达式,重新创建有效的类文件(您可能必须因为不同的字符串长度而调整一些指针)并且它应该可以工作。
即使这个猜测是完全错误的,它也可以作为案例研究,可以帮助你:)