HCL-TECH-SOFTWARE / domino-jnx

Modern Domino Java API based on JNA access to Domino's C API
https://opensource.hcltechsw.com/domino-jnx/
Apache License 2.0
14 stars 3 forks source link

Investigate mechanisms to control agent running ClassLoader #252

Open jesse-gallagher opened 2 years ago

jesse-gallagher commented 2 years ago

Currently, Java agents run via agent.run(...) use the same ClassLoader as the calling code. While this could lead to some interesting uses, it's very desirable to not share this.

We're a bit limited in our options currently, as the entire agent runner code is handled opaquely to us. Agents have a handle on the JNIEnv* value only by way of us calling NotesThread.sinitThread() when present, and then the innards of libnotes handle execution of Java agents. We don't explicitly create this behavior, and there doesn't appear to be a documented way to prevent it.

However, we're in mostly the same boat as lsxbe here: when run in a test case in Eclipse, both JNX and Notes.jar share the running ClassLoader environment. This is different in XPages, however: there, an agent doesn't see classes from the XPages environment. I don't know whether this is because there is special code handling this in the XPages side or if it's due to different types of ClassLoaders.

jesse-gallagher commented 2 years ago

I tested this locally by adding a static value to a utility class in JNX (JNXServiceLoader), then running an agent containing this code:

Class<?> clazz = Class.forName("com.hcl.domino.misc.JNXServiceFinder");
Method m = clazz.getMethod("getVal", new Class<?>[0]);
System.out.println("I see val " + m.invoke(null));

With this, the agent sees the class and the method, and reflects values set outside the agent run.

As Karsten pointed out, it could be that the agent runner uses something like ClassLoader.getSystemClassLoader(), which will share the class-loading space in a test case but would be too low in an XPages environment to see the code there. In that case, it could really end up being a matter of how JNX code is executed and run, more than something specifically that JNX should do.

artcathcl commented 2 years ago

Can you elaborate on it's very desirable to not share this?

jesse-gallagher commented 2 years ago

Agents should have a consistent classpath during execution - this happens to usually be just the stuff from jvm/lib/ext and ndext on Domino, and ideally we'd want to replicate it. There are various issues (version mismatches, extra resources available, etc.) that can crop up if the app-running context of Keep leaks into the agent class space.

It turns out that the agent runner itself doesn't do anything to enforce this, which is why we'd want to investigate options. Most likely, this will end up being a change on the Keep side unless core dev adds a mechanism for us to specify the context ClassLoader (which would be ideal).