1
votes

I'm trying to get a session in java being called from an XPage. The old school way from version 3.0 use to work great:

(Session) Factory.fromLotus(NotesFactory.createSession(), Session.class, null);

But that's no longer available. I tried the code below that I found but I keep getting the following error:

***NO STACK TRACE*** - A session of type CURRENT was requested but no Factory has been defined for that type in this thread.

***NO STACK TRACE*** - Unable to get the session of type CURRENT from the session factory of type null. This probably means that you are running in an unsupported configuration or you forgot to set up your context at the start
of the operation. If you're running in XPages, check the xsp.properties of your database. If you are running in an Agent, make sure you start with a call to Factory.setSession() and pass in your lotus.domino.Session
java.lang.RuntimeException
at org.openntf.domino.utils.Factory.getSession(Factory.java:1012)
at org.openntf.domino.utils.Factory.getSession(Factory.java:859)

The "make sure you start with a call to Factory.setSession() and pass in your lotus.domino.Session" is misleading as setSession() is also no longer available.

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

    Session session = Factory.getSession();

I've installed the OpenNTF API using the Update Site and confirmed they're loaded with the "tell http osgi ss openntf" command. I had an initial issue where it couldn't resolve the Factory, so I copied the four jar files to the ext directory and it solved that issue:

org.openntf.domino.rest_10.0.1.201905061230.jar

org.openntf.domino.xsp_10.0.1.201905061230.jar

org.openntf.domino_10.0.1.201905061230.jar

org.openntf.formula_10.0.1.201905061230.jar

I also tried to hand in a Domino Session in the Factory.startup() call and it still didn't work.

Thanks, Scott

Domino 10.0.1 FP1 openNTF API: OpenNTF-Domino-API-10.0.1.zip

Code where the issue is. This is being called from an XPage. The call is:

<xp:label value="#{javascript:sessionBean.getCoreUser().getUserId();}"/>

This fires the SessionBean Constructor, which calls the startLogging method. That method checks to see if "DebugMode" is turned on. If yes, all debug statements are written to the OpenLog.

private void startLogging() {
        System.out.println("Start OpenLog Logging");

        Session session = (Session) ExtLibUtil.resolveVariable(FacesContext.getCurrentInstance(), "openSession");
        System.out.println("Session: " + session);      

        try {
            ViewEntry valueEntry = session.getCurrentDatabase().getView("SystemConfig").getFirstEntryByKey("DebugMode");
            if (valueEntry != null)             
                SessionBean.debugMode = ("true".equalsIgnoreCase((String) valueEntry.getColumnValue("SetupValue")) ? Boolean.TRUE : Boolean.FALSE);

            System.out.println("Debug Mode set to: " + debugMode);          
        } catch(Exception e) {
            System.out.println("Exception in Start OpenLog Logging");
            e.printStackTrace();            
        }
    } 
2
Have you tried just using Factory.getSession()?Per Henrik Lausten
@Per Henrik Lausten I did try the flat 'getSession()' call initially, but received a 'Factory is not initialized for this thread' error, which started me down the 'Factory.isStarted(), 'Factory.isInitialized()'... path.Scott

2 Answers

0
votes

The way I do this nowadays in a servlet plugin is to have this in the service(HttpServletRequest, HttpServletResponse) method:

Factory.setSessionFactory(() -> AppUtil.getSession(), SessionType.CURRENT);

Where AppUtil.getSession() is a method that tries to find a session for the current context, checking an XPages environment if available, then ContextInfo.getUserSession(), and finally calling NotesFactory.createSession() if it can't find anything.

After setting that, Factory.getSession() will use the provided override instead of its normal behavior.

0
votes

Easiest way is what Jesse has suggested. Use variable resolver. I am getting ODA sessions like this for my application. Here is the updated code to fetch ODA session or domino session as available:

public static Session getSessionAsSigner() {
    Session s = (Session) ExtLibUtil.resolveVariable(FacesContext.getCurrentInstance(), "openSessionAsSigner");
    if (null == s) {
        s = (Session) Factory.getWrapperFactory().fromLotus((lotus.domino.Session)ExtLibUtil.resolveVariable(FacesContext.getCurrentInstance(), "sessionAsSigner"), Session.SCHEMA, null);
    }
    return s;
}

public static Session getSession() {
    Session s = (Session) ExtLibUtil.resolveVariable(FacesContext.getCurrentInstance(), "openSession");
    if (null == s) {
        s = (Session) Factory.getWrapperFactory().fromLotus((lotus.domino.Session)ExtLibUtil.resolveVariable(FacesContext.getCurrentInstance(), "session"), Session.SCHEMA, null);
    }
    return s;
}

I have created a Utils class with static functions for this purpose only.