3

My source code compiles on java 7 and runs on java 11.
I am trying to integrate imperva RASP as a java agent in tomcat. However, when I start the tomcat server, it is throwing following exception:

Caused by: java.lang.IllegalAccessError: class sun.security.ec.ECDSASignature (in module jdk.crypto.ec) cannot access class com.imperva.rasp.AgentBridge (in unnamed module @0x66c61024) because module jdk.crypto.ec does not read unnamed module @0x66c61024
        at jdk.crypto.ec/sun.security.ec.ECDSASignature.<init>(ECDSASignature.java:118)
        at jdk.crypto.ec/sun.security.ec.ECDSASignature.<init>(ECDSASignature.java:106)
        at jdk.crypto.ec/sun.security.ec.ECDSASignature$SHA1.<init>(ECDSASignature.java:214)
        at jdk.crypto.ec/sun.security.ec.SunEC$ProviderService.newInstance(SunEC.java:102)
        at java.base/java.security.Signature.isSpi(Signature.java:331)

The way I am passing java agent is:

JAVA_OPTS="-javaagent:$IMPERVA_JAR $JAVA_OPTS"

I went through multiple posts such as this one about --add-opens argument. Based on that, I am passing JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=jdk.crypto.ec/sun.security.ec=ALL-UNNAMED" I can see following statement in the logs:

Picked up JDK_JAVA_OPTIONS:  --add-opens=jdk.crypto.ec/sun.security.ec=ALL-UNNAMED

Am I missing something here or is there any syntax error in the arguments that I am passing?
There is no any other configuration is done.

Any help is appreciated. Thank you.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • 2
    Opening `jdk.crypto.ec/sun.security.ec` to `ALL-UNNAMED` would only be useful if the access was from the unnamed module to `jdk.crypto.ec/sun.security.ec`, but according to the error, the access is the other way round. For the access as indicated by the exception, no *opens* directive is necessary, as the unnamed module is open anyway. What is missing, is a *read edge*, but such a read edge can only be [added at runtime](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Module.html#addReads(java.lang.Module)); there’s no command line option for that. – Holger Apr 25 '22 at 12:12
  • 1
    If you transform `sun.security.ec.ECDSASignature`, JVMTI should [add a read edge to the unnamed module](https://docs.oracle.com/en/java/javase/11/docs/specs/jvmti.html#bcimodules). You can also use `Instrumentation` to [add a read edge](https://docs.oracle.com/en/java/javase/18/docs/api/java.instrument/java/lang/instrument/Instrumentation.html#redefineModule%28java.lang.Module,java.util.Set,java.util.Map,java.util.Map,java.util.Set,java.util.Map%29) by hand. – Johannes Kuhn Apr 25 '22 at 12:18
  • @Holger and johannes - Thank you, but adding some code related to this may not work as the compilations happens on jdk7. Also the agent jar is out of my scope to change as its pre-built. – Bhushan Karmarkar Apr 26 '22 at 04:55
  • 2
    Well, if there’s no newer version of the agent which does the necessary steps for newer Java versions, you have to stay with an older Java version. And think about a future strategy without relying on unmaintained software. It’s possible to write Java 7 software which does these steps via Reflection when running on a newer Java version, however, it’s still the duty of the Java Agent. – Holger Apr 26 '22 at 07:04
  • Thanks, I agree. I managed to resolve this and proceed further. Instead of --add-opens, I used --add-reads and it went ahead. – Bhushan Karmarkar Apr 26 '22 at 11:39
  • @Holger, why would you say that you can add a read edge only during runtime, even though there is a JVM option `--add-reads` for it? – kriegaex Apr 29 '22 at 07:17
  • 1
    @kriegaex I wasn’t aware of the option, however, if you have a Java Agent injecting dependencies dynamically at runtime, specifying the necessary read edges statically at startup time is a maintenance nightmare anyway. That might help temporarily but actually, the duty of adding the read edge is at the agent that added the dependency. – Holger Apr 29 '22 at 07:28
  • I would not have thought that I live to see the day when you are unaware of an option. I always perceived you as some kind of omniscient oracle with regard to all things JVM. At any rate, you know much more about it than I do. With regard to Java modules, I would even consider myself not much more than an ignorant noob, trying as hard as I can to ignore the existence of a Java module concept, seeing not much value in it. – kriegaex Apr 29 '22 at 07:54
  • 2
    @kriegaex well, in a correctly configured environment, there should be no need for `--add-reads` or `--add-opens` and I use neither. I’m only aware of the latter, because there’s too much software with reflective hacks out there (and a lot of related SO questions). Since affected software typically resides in the unnamed module, it makes sense to only stumble over the need for `--add-opens`, as read edges are already implied for non-modular software. So the need for `--add-reads` is a very special corner case. Even in this specific case, it shouldn’t be handled on the command line, actually. – Holger Apr 29 '22 at 08:09

1 Answers1

3

Managed to solve it by using --add-reads instead of --add-opens.

JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-reads jdk.crypto.ec=ALL-UNNAMED"