Java bytecode not in .class file

119 views Asked by At

I'm working on a personal project just for fun, a new programming languages (just because there are not enough). I m going to make it run on JVM but I need to store some metadata in the compiled file. So I have two alternatives, create two separated file(one with metadata and one with bytecode), or put metadata and bytecode in the same file. I would like to choose the second one, my only problem is how do I tell the jvm how to extract the bytecode from the compiled file? I thought to create a specific version of an already existent jvm changing the source code but maybe there is a easier way.

Thank you in advance

EDIT

The metadata I need to store are useful only during compilation and not during runtime

2

There are 2 answers

1
rzwitserloot On

AnyClassYouWant.class.getResourceAsStream("AnyClassYouWant.class") works - at least, for any non-inner class. For inner classes you'd have to ask for "OuterClassName$InnerClass.class" instead. This gets you the raw bytes. For anything, and for classes whose files can be anywhere (in a jar, on disk, fetched from the network, loaded by some module loading system, generated on the fly, you name it).

The class file format is not the best place to attempt to store random data and javac cannot be coerced to do it, you'd have to write a tool that takes an existing class file and adds metadata to it, which is complicated, but, possible. It's not how java tools tend to work: Instead they pack such things into a separate file, use the same .getResourceAsStream mechanism to load it, and distribute as jar files. There are no real downsides to shipping your data in a separate 'file' if all files just end up as entries in a jar, after all.

Thus, this answer explains how to do it, but comes with the rider of: But, really, don't.

4
Thomas Kläger On

The Java Class File Format allows you to add arbitrary attributes to various elements, see 4.7 Attributes.

You can use this mechanism to add your metadata to your custom made class files while still generating class files that a standard JVM can load.

Compilers for the JVM like the Scala compiler (and probably the Kotlin compiler too) already use this.


put metadata and bytecode in the same file:

This is exactly what the attributes allow you to do. And you can attach the attributes to the different parts of the class file

  • to the class itself if they are applicable to the complete class
  • to the methods if they are specific for a method
  • to the fields if they are specific for a field

I thought to create a specific version of an already existent jvm changing the source code but maybe there is a easier way:

Adding your attributes to the class files you produce by using the existing mechanism of adding custom attributes is certainly much easier than creating your own JVM.

The metadata I need to store are useful only during compilation and not during runtime:

This is expected. The JVM will ignore your attributes when loading the classes at runtime.

If your attributes contain trade secrets that you don't want to make publicly available you can still filter them out from the class files before publishing the class files to some public repository.