You have noticed that the term βusually,β as well as the lack of a description of byte code in JLS, is intended to define the Java programming language as independent of the runtime environment as possible. However, it is not so simple:
As noted above, this specification often refers to the Java SE platform API classes. In particular, some classes have a special relationship with the Java programming language. Examples include classes such as Object , Class , ClassLoader , String , Thread , and classes and interfaces in the java.lang.reflect , among others. This specification restricts the behavior of such classes and interfaces, but does not provide a complete specification for them. The reader refers to the Java SE platform API documentation.
Therefore, this specification does not describe the reflection in detail. Many linguistic constructs have analogues in the Core Reflection API ( java.lang.reflect ) and language model API ( javax.lang.model ), but they are not usually discussed here. For example, when we list ways to create an object, we usually donβt include the ways in which the Core Reflection API can do this. Readers should be aware of these additional mechanisms, even if they are not mentioned in the text.
Thus, the Java programming language is larger than JLS, as well as the Java SE platform API. And there, we have the defineClass methods of the mentioned defineClass class that accept input in the format of the class file. Therefore, even if we use other deployment methods than class files in bytecode format, a fully compatible environment should support this format in this place. Note that Java 9 introduced another method that accepts input in the class file format , which does not even require Reflection or the implementation of custom class loaders.
This excludes JavaME, which does not have these API artifacts mentioned by JLS, otherwise we already had an example Java environment that does not support bytecode manipulation.
But this still does not fully answer the question of whether bytecode manipulation outside the language works, speaking of JavaSE or EE. Even if the support for the bytecode format is provided by the standard API, the control of the bytecode depends on the implementation details, either the Instrumentation API, which is optional, or processes the compiled class files in their expanded form as a file hierarchy, jar files, or module files, and it is not guaranteed that this will be a deployed form of the application (as said at the beginning). Thus, it is actually impossible to implement a bytecode manipulation tool that is guaranteed to work with all possible Java environments, although you will need to make longer lengths to create an environment that is fully compatible, but does not work with these tools ...