Skip to Content

Archived discussions are read-only. Learn more about SAP Q&A

CR Server 2008 / Using openDocument interface with a no-logon wrapper

Hi, all!

I had a problem with the openDocument.jsp interface and a no-logon wrapper which took me quite a while to figure out. I'm now posting these results here in the hopes that someone else will find them useful. Of course, if anyone has input how to improve the solution, it's also welcome!

The system on which this was developed and tested was a vanilla Crystal Reports Server 2008 installation on Tomcat / MySQL / Windows Server 2003.

The problem was that calls to openDocument interface left sessions open and this quickly led to the situation where all the concurrent access licenses (CALs) were used. It seemed nondeterministic when a session was released; it could have been minutes or hours.

The solution: write a HTTP session timeout listener which logoffs the CRS-backend session. (The code below has still some dubug output enabled.)

package fi.niscayah.util;

import com.crystaldecisions.sdk.framework.IEnterpriseSession;
import javax.servlet.http.*;
import java.util.Date;
import java.util.Enumeration;
import java.text.SimpleDateFormat;


public class KillSession implements HttpSessionListener
{
    public void sessionCreated(HttpSessionEvent event)
    {
        debug("sessionCreated()", event);
    }

    public void sessionDestroyed(HttpSessionEvent event)
    {
        HttpSession session = event.getSession();
        try {
            java.util.Enumeration name = session.getAttributeNames();
            while (name.hasMoreElements()) {
                String attributeName = (String)name.nextElement();
                Object attribute = session.getAttribute(attributeName);
                if((attribute != null) && (attribute instanceof IEnterpriseSession)) {
                    debug("  attribute : " + attributeName);
                    debug("  type      : " + attribute.getClass().getName());
                    IEnterpriseSession ies = (IEnterpriseSession)attribute;
                    ies.logoff();
                }
            }
            debug("sessionDestroyed()", event);
        } catch (Exception ex) {
            debug("sessionDestroyed() exception");
        }
    }
    
    private void debug(String msg)
    {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        String timestamp = sdf.format(new Date());
        
        System.err.println("[KillSession] [" + timestamp + "] " + msg);
    }
    
    private void debug(String msg, HttpSessionEvent event)
    {
        HttpSession session = event.getSession();
        String id = session.getId();
        String context = session.getServletContext().getServletContextName();
        
        debug("[" + context + "] [" + id + "] " + msg);
    }
}

(If you want to test the above code, create a .jar package out of it and put it in webapps/OpenDocument/WEB-INF/lib.)

Next we need to register our listener. I noticed that the openDocument-webapp's web.xml-file already contained a listener definition that claimed to expire enterprise sessions on HTTP timeout. I never saw such results; I tested it by registering my own listener, which only outputted debug information, and then when ever a session timeout happened, I checked the amount of licenses in use via the CMC - it never dropped predictably.

So, comment out the SessionCleanupListener and add KillSession.

<!-- SK: Added own listener. -->
<listener>
    <listener-class>fi.niscayah.util.KillSession</listener-class>
</listener>
    
<!-- SK: Commented out. -->
<!-- SessionCleanupListener is used to expire the EnterpriseSession when the web session is timeout -->    
<!-- <listener>
    <listener-class>com.businessobjects.sdk.ceutils.SessionCleanupListener</listener-class>
</listener> -->

After the above, change the HTTP session timeout to something more suitable. If you're creating really big reports, one minute might be too little. Also notice, that the value is an approximation. The timeout event might happen just as one minute has passed, but usually it takes more.

<session-config>
    <session-timeout>1</session-timeout>
</session-config>

Now we're good to go and test the openDocument interface. The result should be that every time a HTTP session timeouts, an enterprise session (which was initialized via the openDocument call) is logged off.

Next the no-logon wrapper.

I found a lot of examples for logging in automatically, but every one of them exhibited a strange behavior (at least when used in conjunction with the openDocument interface) where the session count was increased by two. A lot of head scratching later, the solution below was devised.

<%@ page language="java"
    import = "com.crystaldecisions.sdk.framework.CrystalEnterprise,
              com.crystaldecisions.sdk.framework.IEnterpriseSession,
              com.crystaldecisions.sdk.framework.ISessionMgr,
              com.crystaldecisions.sdk.exception.SDKException"
%>

<%
ISessionMgr sessionManager = CrystalEnterprise.getSessionMgr();
IEnterpriseSession entSession = sessionManager.logon("Guest", "", "<server>:6400", "secEnterprise");
String entToken = entSession.getLogonTokenMgr().createWCAToken("", 1, 1);

// So that this can be logged off when the session timeouts
HttpSession httpSession = request.getSession();
httpSession.setAttribute("nologon_SESSION", entSession);

String query = request.getQueryString();   	
String redirectURL = "http://<server>:8080/OpenDocument/opendoc/openDocument.jsp?" +
    query + "&token=" + entToken;

response.sendRedirect(redirectURL);
%>

You can put the above .jsp-file where you like, but I dropped it in webapps/openDocument, since it's no use by itself.

The use of nologon.jsp is simple: use it as you would openDocument.jsp.

And there you have it. A word of warning though, if you're not sure what you're doing, I wouldn't recommend trying these things out. And you certainly shouldn't deploy these on a production environment.

As said before, any input is welcome!

Former Member
Not what you were looking for? View more on this topic or Ask a question