0

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

1
  • 3
    Storing extra metadata in class files? Sounds a bit like annotations. I suggest you take a closer look at those if they fit your use-case. Commented Nov 28, 2023 at 8:46

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for the answer but I did not make my self clear, I edit the question
@rain183: I don't see how your edit invalidates anything in this answer. The metadata might only be useful at compile time, but you can still store it in attributes of the class just fine. That's exactly how CLASS retention annotations are stored as well (and they are not accessible/used at runtime either).
@rain183 the metadata that the Scala compiler adds to the class files is only usefull for the Scala compiler during the compilation of Scala source files.
@rain183 of course, you could also create your own file format for compile time, to be converted to standard class files during deployment. But your question was “how do I tell the jvm how to extract the bytecode from the compiled file” which implies that the deployed format still contains the meta information or in other words, that you’re using the same file format at compile time and at runtime. This is addressed by this answer.
1

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.

1 Comment

Thank you for the answer but I did not make my self clear, I edit the question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.