OpenNTF/org.openntf.domino

Openntf added to ibm domino agent but getting illegalstateexception

Closed this issue · 11 comments

Hello,
I have these files: https://github.com/OpenNTF/org.openntf.domino 
I created a java agent in lotus domino designer.
I added the jar: org.openntf.domino to the java agent.
This is the code in the java agent:

import org.openntf.domino.*; public class JavaAgent extends AgentBase { public void NotesMain() { try { Session session = getSession(); AgentContext agentContext = session.getAgentContext(); System.out.println("test"); // (Your code goes here) } catch(Exception e) { e.printStackTrace(); } } }

And when I run it I get this error:
java.lang.IllegalStateException: org.openntf.domino.utils.Factory is not initialized for this thread! at org.openntf.domino.utils.Factory.getThreadVariables(Factory.java:345) at org.openntf.domino.utils.Factory.getWrapperFactory(Factory.java:627) at org.openntf.domino.AgentBase.getSession(AgentBase.java:25) at JavaAgent.NotesMain(Unknown Source) at lotus.domino.AgentBase.runNotes(Unknown Source) at lotus.domino.NotesThread.run(Unknown Source) Factory.getSession(); does not work

What am I doing wrong here?

That message indicates that you should call the Factory.initThread at the top of the agent, something like:

if (!Factory.isInitialized()) {
	Factory.initThread(new Factory.ThreadConfig(new Fixes[0], AutoMime.WRAP_32K, true));
}

Then, in a finally block at the end of the main try/catch statement, call:

try {
	...
} catch(Exception e) {
	...
} finally {
	Factory.termThread();
}

Use in agents is something we've de-facto deprecated over the years, however. It may very well work, but we haven't been testing that in releases recently.

It cannot find the Factory class.
I only imported:
import org.openntf.domino.*;

The full class name is org.openntf.domino.utils.Factory. In turn, Fixes is org.openntf.domino.ext.Session.Fixes. If you hover over the unknown class names, it's likely that Designer will provide appropriate suggestions for the imports for you.

Yes most of the times it does, but for Factory it did not.

So I currently got this:

`import org.openntf.domino.*;
import org.openntf.domino.ext.Session.Fixes;
import org.openntf.domino.utils.Factory;

public class JavaAgent extends AgentBase {

public void NotesMain() {

  try {
	  if (!Factory.isInitialized()) {
		  System.out.println("te3434st");
			Factory.initThread(new Factory.ThreadConfig(new Fixes[0], AutoMime.WRAP_32K, true));
		}
      Session session = getSession();
      AgentContext agentContext = session.getAgentContext();
      System.out.println("test");
      // (Your code goes here)

  } catch(Exception e) {
      e.printStackTrace();
   }
 finally {
	Factory.termThread();
}
}

}
`

And it outputs me this:
te3434st
java.lang.IllegalStateException: Factory is not yet started
at org.openntf.domino.utils.Factory.initThread(Factory.java:1157)
at JavaAgent.NotesMain(Unknown Source)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(Unknown Source)
jul 19, 2017 2:46:23 PM org.openntf.domino.utils.Factory termThread
SEVERE: WARNING - Thread AgentThread: JavaAgent was not correctly initalized or terminated twice
java.lang.Throwable
at org.openntf.domino.utils.Factory.termThread(Factory.java:1178)
at JavaAgent.NotesMain(Unknown Source)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(Unknown Source)

Heh, that thing's picky. Maybe try adding a:

if(!Factory.isStarted()) {
	Factory.startup();
}

I think this gonna be a difficult one hehe:

 if(!Factory.isStarted()) {
    Factory.startup();
 }
 if (!Factory.isInitialized()) {
    System.out.println("te3434st");
    Factory.initThread(new Factory.ThreadConfig(new Fixes[0], AutoMime.WRAP_32K, true));
 }

produces:

[ODA] Starting the OpenNTF Domino API... Using notes.ini: C:\Program Files (x86)\IBM\Notes\notes.ini
[ODA] OpenNTF API Version 0.0.0.unknown started
Logging.logCfgFilePrecheck: File 'c:\Program Files (x86)\IBM\Notes\Data/IBM_TECHNICAL_SUPPORT/org.openntf.domino.logging.logconfig.properties' not found
Logging: Couldn't initialize from PropertyFile; activating fallback ...
java.security.AccessControlException: Access denied ("java.util.logging.LoggingPermission" "control")
at java.security.AccessController.throwACE(AccessController.java:157)
at java.security.AccessController.checkPermissionHelper(AccessController.java:217)
at java.security.AccessController.checkPermission(AccessController.java:349)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:562)
at COM.ibm.JEmpower.applet.AppletSecurity.superDotCheckPermission(AppletSecurity.java:1455)
at COM.ibm.JEmpower.applet.AppletSecurity.checkPermission(AppletSecurity.java:1625)
at COM.ibm.JEmpower.applet.AppletSecurity.checkPermission(AppletSecurity.java:1470)
at java.util.logging.LogManager.checkPermission(LogManager.java:1597)
at java.util.logging.Logger.checkPermission(Logger.java:433)
at java.util.logging.Logger.setLevel(Logger.java:1700)
at org.openntf.domino.logging.Logging.startUpFallback(Logging.java:156)
at org.openntf.domino.logging.Logging.startUp(Logging.java:55)
at org.openntf.domino.utils.Factory$4.run(Factory.java:1343)
at java.security.AccessController.doPrivileged(AccessController.java:650)
at org.openntf.domino.utils.Factory.startup(Factory.java:1340)
at org.openntf.domino.utils.Factory.startup(Factory.java:1263)
at JavaAgent.NotesMain(Unknown Source)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(Unknown Source)
te3434st
jul 19, 2017 2:48:37 PM org.openntf.domino.utils.Factory getWrapperFactory
WARNING: Getting default WrapperFactory
java.lang.NoClassDefFoundError: org.openntf.service.ServiceLocatorFinder
at org.openntf.domino.utils.Factory.findApplicationServices(Factory.java:1105)
at org.openntf.domino.utils.Factory.getWrapperFactory(Factory.java:631)
at org.openntf.domino.AgentBase.getSession(AgentBase.java:25)
at JavaAgent.NotesMain(Unknown Source)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.openntf.service.ServiceLocatorFinder
at lotus.domino.AgentLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(ClassLoader.java:809)
... 6 more

java.security.AccessControlException: Access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
at java.security.AccessController.throwACE(AccessController.java:157)
at java.security.AccessController.checkPermissionHelper(AccessController.java:217)
at java.security.AccessController.checkPermission(AccessController.java:349)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:562)
at COM.ibm.JEmpower.applet.AppletSecurity.superDotCheckPermission(AppletSecurity.java:1455)
at COM.ibm.JEmpower.applet.AppletSecurity.checkPermission(AppletSecurity.java:1625)
at COM.ibm.JEmpower.applet.AppletSecurity.checkPermission(AppletSecurity.java:1470)
at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:143)
at org.openntf.domino.impl.Base$1.run(Base.java:168)
at java.security.AccessController.doPrivileged(AccessController.java:650)
at org.openntf.domino.impl.Base.(Base.java:156)
at org.openntf.domino.impl.WrapperFactory.wrapLotusObject(WrapperFactory.java:532)
at org.openntf.domino.impl.WrapperFactory.fromLotusObject(WrapperFactory.java:277)
at org.openntf.domino.impl.WrapperFactory.fromLotus(WrapperFactory.java:190)
at org.openntf.domino.impl.WrapperFactory.fromLotus(WrapperFactory.java:150)
at org.openntf.domino.AgentBase.getSession(AgentBase.java:25)
at JavaAgent.NotesMain(Unknown Source)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(Unknown Source)
Exception in thread "AgentThread: JavaAgent" java.lang.ExceptionInInitializerError
at java.lang.J9VMInternals.ensureError(J9VMInternals.java:141)
at java.lang.J9VMInternals.recordInitializationFailure(J9VMInternals.java:130)
at org.openntf.domino.impl.WrapperFactory.wrapLotusObject(WrapperFactory.java:532)
at org.openntf.domino.impl.WrapperFactory.fromLotusObject(WrapperFactory.java:277)
at org.openntf.domino.impl.WrapperFactory.fromLotus(WrapperFactory.java:190)
at org.openntf.domino.impl.WrapperFactory.fromLotus(WrapperFactory.java:150)
at org.openntf.domino.AgentBase.getSession(AgentBase.java:25)
at JavaAgent.NotesMain(Unknown Source)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(Unknown Source)
Caused by: org.openntf.domino.exceptions.OpenNTFNotesException
at org.openntf.domino.utils.DominoUtils.handleException(DominoUtils.java:424)
at org.openntf.domino.utils.DominoUtils.handleException(DominoUtils.java:406)
at org.openntf.domino.impl.Base.(Base.java:193)
... 8 more
Caused by: java.security.AccessControlException: Access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
at java.security.AccessController.throwACE(AccessController.java:157)
at java.security.AccessController.checkPermissionHelper(AccessController.java:217)
at java.security.AccessController.checkPermission(AccessController.java:349)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:562)
at COM.ibm.JEmpower.applet.AppletSecurity.superDotCheckPermission(AppletSecurity.java:1455)
at COM.ibm.JEmpower.applet.AppletSecurity.checkPermission(AppletSecurity.java:1625)
at COM.ibm.JEmpower.applet.AppletSecurity.checkPermission(AppletSecurity.java:1470)
at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:143)
at org.openntf.domino.impl.Base$1.run(Base.java:168)
at java.security.AccessController.doPrivileged(AccessController.java:650)
at org.openntf.domino.impl.Base.(Base.java:156)
... 8 more

I was afraid of something like that. There are a few options, both with tradeoffs:

  • Alter the Java policy by adding a file named java.pol in jvm/lib/security containing grant { permission java.security.AllPermission; };. This would have the down side of having to make this filesystem-side change on each Notes/Domino instance running the agent
  • Put the ODA jar in jvm/lib/ext. This would have the same problem as above but would also likely make it so that you'd run into problems with using ODA in XPages. If you use the same version in both cases, it MAY work, but you may also run into ClassLoader-related issues even if the versions match.

Hmm, do you also suggest using something else then the deprecated agents??

It's a messy problem, really. In most cases where I've had to have scheduled Java agent code, I've just used the vanilla lotus.domino classes for agents. Some people are fans of having a scheduled agent that calls an XPage or service URL via HTTP to do the actual work. In other cases, I've had plugins that launch scheduled tasks with a scheduler framework, though that particular one isn't open source. We've discussed adding a scheduler to Xots, potentially piggybacking on the existing Quartz project, but that hasn't been fully implemented. I'm not sure what the other major ODA users use.

The Xots class has schedule() methods. I only came across them recently, but they may be a way of scheduling Java code. However, there still needs to be something to create an instance of the Java runnable to Xots, some way to "unload" it from Xots as required (new version deployed etc). Ideally the schedule would be separate from the Xots Runnable / Callable, so you could have different schedules for different servers / environments. However, then it's a challenge of loading the class when all you have is the Java class name and an NSF path for where the code resides. If the Java class is in a plugin, it may be easier, although the relevant plugin needs adding dynamically to the classpath. A ServiceLoader may help, but it might have the wrong ClassLoader. See https://wiki.openntf.org/display/DesLite/Spec for more detail on what I would like to be able to achieve.