我正在做一个个人项目,只是为了好玩,一种新的编程语言,我打算让它在JVM上运行,但我需要在编译后的文件中存储一些元数据。(一个包含元数据,一个包含字节码),或者将元数据和字节码放在同一个文件中。我想选择第二个,我唯一的问题是我如何告诉jvm如何从编译的文件中提取字节码?我想创建一个特定版本的已经存在的jvm更改源代码,但也许有一个更简单的方法。提前感谢您编辑我需要存储的元数据只在编译期间有用,而在运行时则没有用
xtfmy6hx1#
Java Class File Format允许你为各种元素添加任意属性,参见4.7属性。您可以使用这种机制将元数据添加到定制的类文件中,同时仍然生成标准JVM可以加载的类文件。像Scala编译器(可能还有Kotlin编译器)这样的JVM编译器已经使用了它。
这正是属性允许你做的事情。你可以把属性附加到类文件的不同部分
使用现有的添加自定义属性的机制将属性添加到您生成的类文件中肯定比创建您自己的JVM要容易得多。
这是预期的。JVM在运行时加载类时将忽略您的属性。如果属性包含不想公开的商业机密,您仍然可以在将类文件发布到某个公共存储库之前将它们从类文件中过滤掉。
9ceoxa922#
AnyClassYouWant.class.getResourceAsStream("AnyClassYouWant.class")可以工作--至少,对于任何非内部类。对于内部类,你必须请求"OuterClassName$InnerClass.class"。这会得到原始字节。对于任何东西,以及文件可以在任何地方的类(在jar中,在磁盘上,从网络中获取,由一些模块加载系统加载,动态生成,你可以命名它)。类文件格式并不是存储随机数据的最佳方式,而且javac也不能强制执行,你必须编写一个工具来获取现有的类文件并向其中添加元数据,这很复杂,但也是可能的。这不是java工具的工作方式:相反,它们将这些东西打包到一个单独的文件中,使用相同的.getResourceAsStream机制来加载它,并作为jar文件分发。毕竟,如果所有文件最终都作为jar中的条目,那么将数据放在一个单独的“文件”中并没有真实的缺点。因此,这个答案解释了如何做到这一点,但附带的骑手:但是,真的,不要。
AnyClassYouWant.class.getResourceAsStream("AnyClassYouWant.class")
"OuterClassName$InnerClass.class"
javac
.getResourceAsStream
2条答案
按热度按时间xtfmy6hx1#
Java Class File Format允许你为各种元素添加任意属性,参见4.7属性。
您可以使用这种机制将元数据添加到定制的类文件中,同时仍然生成标准JVM可以加载的类文件。
像Scala编译器(可能还有Kotlin编译器)这样的JVM编译器已经使用了它。
这正是属性允许你做的事情。你可以把属性附加到类文件的不同部分
使用现有的添加自定义属性的机制将属性添加到您生成的类文件中肯定比创建您自己的JVM要容易得多。
这是预期的。JVM在运行时加载类时将忽略您的属性。
如果属性包含不想公开的商业机密,您仍然可以在将类文件发布到某个公共存储库之前将它们从类文件中过滤掉。
9ceoxa922#
AnyClassYouWant.class.getResourceAsStream("AnyClassYouWant.class")
可以工作--至少,对于任何非内部类。对于内部类,你必须请求"OuterClassName$InnerClass.class"
。这会得到原始字节。对于任何东西,以及文件可以在任何地方的类(在jar中,在磁盘上,从网络中获取,由一些模块加载系统加载,动态生成,你可以命名它)。类文件格式并不是存储随机数据的最佳方式,而且
javac
也不能强制执行,你必须编写一个工具来获取现有的类文件并向其中添加元数据,这很复杂,但也是可能的。这不是java工具的工作方式:相反,它们将这些东西打包到一个单独的文件中,使用相同的.getResourceAsStream
机制来加载它,并作为jar文件分发。毕竟,如果所有文件最终都作为jar中的条目,那么将数据放在一个单独的“文件”中并没有真实的缺点。因此,这个答案解释了如何做到这一点,但附带的骑手:但是,真的,不要。