OpenNTF / org.openntf.domino

Open replacement for lotus.domino package in HCL Domino
Apache License 2.0
65 stars 34 forks source link

Openntf added to ibm domino agent but getting illegalstateexception #162

Closed nensing closed 4 years ago

nensing commented 6 years ago

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?

jesse-gallagher commented 6 years ago

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.

nensing commented 6 years ago

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

jesse-gallagher commented 6 years ago

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.

nensing commented 6 years ago

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

nensing commented 6 years ago

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)

jesse-gallagher commented 6 years ago

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

if(!Factory.isStarted()) {
    Factory.startup();
}
nensing commented 6 years ago

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

jesse-gallagher commented 6 years ago

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

nensing commented 6 years ago

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

jesse-gallagher commented 6 years ago

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.

paulswithers commented 6 years ago

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.