Closed rupinder10 closed 1 month ago
Why can you not add an --add-opens command line parameter? If you need to ship this to a client that cannot provide them directly you need to bake it into the runtime
Starting from Java 9, Instrumentation
provides the redefineModule
and isModifiableModule
methods, which allow you to modify module visibility.
In Byte Buddy, you might want to look into AgentBuilder.assureReadEdgeFromAndTo
and ClassInjector.UsingInstrumentation.redefineModule
, as these could be helpful.
@rupinder10 I would strongly advise against going down this path, since reflecting on internal implementation details, even of otherwise public classes are not guaranteed to be forward-compatible with newer version of the JDK as they are released. Provide the functionality that you need yourself or continue down the path of future technical debt.
@rupinder10 I do not know your problem well enough to recommend anything, but if you just want to get this working, you could look into ByteBuddyAgent.install()
and use redefineModule
, all without code instrumentation. From Java 22, this stops working, too, and you will have to register an agent on the command line.
Thanks for the responses everybody. @anders-steen-dige-madsen why I can't add --add-opens is because its an agent I am building for an application that I don't own. So I dont want to add an additional requirement on the product vendor to have to change their startup scripts. And even if they could, it requires them to restart the application. Currently my agent works by just dropping it into the product's namespace folder.
Looks like there is no elegant way to do it anyway as the solutions will only work temporarily. So -add-opens it will have to be with a JVM restart required.
As an agent, you configure add-opens via the Instrumentation API. It has redefefineModule for it.
As an agent, you configure add-opens via the Instrumentation API. It has redefefineModule for it.
But as you mentioned that will stop working with Java 22. Or did I misunderstand that ?
No, only dynamic attach, not the module retransformation.
I guess that could have some use. Although if I have to add an agent on the command line, I would have to shutdown the JVM anyway. which means I could also add the -add-opens at the same time. My original need was to avoid the restart of the JVM.
If you have an agent, you can add your own interface to communicate with the running JVM. You can open a socket, for example, or use a file for communication. Just make sure you validate such requests to avoid exposing the VM.
I didn't get that. Can you provide specifics to what you mean ?
If you install an agent once on the command line, you can update your instrumentation dynamically thereafter using your own communication channel. As long as you attached an agent that is capable of that upon the first startup.
Thanks for the responses everybody. @anders-steen-dige-madsen why I can't add --add-opens is because its an agent I am building for an application that I don't own. So I dont want to add an additional requirement on the product vendor to have to change their startup scripts. And even if they could, it requires them to restart the application. Currently my agent works by just dropping it into the product's namespace folder.
Looks like there is no elegant way to do it anyway as the solutions will only work temporarily. So -add-opens it will have to be with a JVM restart required.
Then you are putting the onus on your customer. Instead you should plan for Integrity by Default and make sure to notify them before hand so they can change it to only run on startup instead of dynamically since that will not be allowed by default going forward in Java 24+.
All good arguments. My product is a troubleshooting product for a java server. Customers typically activate it when they think they have an issue. The instrumentation kicks in and starts collecting all the data. With dynamic instrumentation going away, the customer would have to shutdown the JVM, add the the command line and restart. But that resolves the issue. Hence the concern. Off course, the alternative would be to add the command line and then add some switches to activate and deactivate the instrumentation, as @raphw suggested
I have some code developed with Java 8 that uses reflection to call a private method in URLClassLoader. Unfortunately, this isnt possible in Java 17 so the application stops working in Java 17 because the
setAccessible(true) in java.lang.reflect.Method in no longer works. This requires an --add-opens command line parameter. But I cannot do this for a few different reasons.
I was thinking maybe I can add a new class using ByteBuddy into the java.base module and then let that handle this code. Is this possible ? If yes, how can I add a new class to an existing module ?