About   Forum   Wiki   Home  

       
    Managed Chaos      
   
Naresh Jain’s Weblog on Object thinking, Patterns, Open Source, Agile and Adventure Sports

 
`
 
Tags
Recent Comments
Quick Search
Recent Entries
Categories
Archives
February 2005
M T W T F S S
« Jan   Mar »
 123456
78910111213
14151617181920
21222324252627
28  
Add to Technorati Favorites

Syndicate This Blog
Entries (RSS)
Comments (RSS)

Archive for February, 2005

Crystal Reports PLUS Struts

Monday, February 14th, 2005

<b>Steps to integrate crystal reports with Strut’s app</b>

1. Provide a link from your web-app, which will trigger the report. Usually we have a form, which will do this.
html:form action=”/generateReport” target=”_blank”

2. Update the struts-congif.xml file to redirect “/generateReport” to the appropriate action class

3. Write the following GenerateReportAction class to handle the report generation logic.

That’s it. You will see the report.

package com.xyz.abc.web.servlet;

import com.crystaldecisions.report.web.viewer.CrystalReportViewer;
import com.crystaldecisions.reports.reportengineinterface.JPEReportSourceFactory;
import com.crystaldecisions.sdk.occa.report.data.Fields;
import com.crystaldecisions.sdk.occa.report.data.ParameterField;
import com.crystaldecisions.sdk.occa.report.lib.ReportSDKExceptionBase;
import com.crystaldecisions.sdk.occa.report.reportsource.IReportSource;
import com.crystaldecisions.sdk.occa.report.reportsource.IReportSourceFactory2;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

public class GenerateReportAction extends Action {
public ActionForward actionExecuted(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, ActionErrors errors) throws IOException, ServletException {
String reportName = System.getProperty(REPORT_NAME, “Report1.rpt”);
final ActionForm reportForm = (ReportForm) form;
List paramList = getReportParams(reportForm);
CrystalReportViewer reportViewer = createReportViewer(reportName, paramList, request.getLocale());
try {
reportViewer.processHttpRequest(request, response, getServlet().getServletContext(), response.getWriter());
} catch (ReportSDKExceptionBase reportSDKExceptionBase) {
reportSDKExceptionBase.printStackTrace();
} finally {
reportViewer.dispose();
}
return (mapping.findForward(”success”));
}

private CrystalReportViewer createReportViewer(String reportName, List params, Locale locale) {
CrystalReportViewer reportViewer = new CrystalReportViewer();
try {
IReportSourceFactory2 rptSrcFactory = new JPEReportSourceFactory();
IReportSource reportSource = (IReportSource) rptSrcFactory.createReportSource(reportName, locale);
reportViewer.setReportSource(reportSource);
Fields fields = createParamterFields(params);
reportViewer.setParameterFields(fields);
setReportViewerProperties(reportViewer);

return reportViewer;
} catch (ReportSDKExceptionBase e) {
throw new IllegalStateException(e.getMessage());
}
}

private Fields createParamterFields(List params) {
Fields fields = new Fields();
for (Iterator iterator = params.iterator(); iterator.hasNext();) {
ReportParams reportParam = (ReportParams) iterator.next();
ParameterField parameterField = newParameterField(reportParam.getParamName(), reportParam.getParamValue());
fields.add(parameterField);
}
return fields;
}

private void setReportViewerProperties(CrystalReportViewer reportViewer) {
reportViewer.setHasRefreshButton(false);
reportViewer.setHasExportButton(true);
reportViewer.setEnableParameterPrompt(true);
reportViewer.setEnableLogonPrompt(true);
reportViewer.setHasLogo(false);
}

private ArrayList getReportParams(ActionForm ReportForm) {
ArrayList outParamList = new ArrayList();
outParamList.add(new ReportParams(”param1″, ReportForm.getParamOne()));

return outParamList;
}

public static ParameterField newParameterField(String name, String dataValue) {
ParameterField field = new ParameterField();
field.setName(name);
field.setReportName(”");
field.getCurrentValues().add(dataValue);
return field;
}
}

Things to watch out:

1. html:form action=”/generateReport” target=”_blank”
Since crystal report has it’s own menu, it’s better to open the report in a separate blank page. If we don’t do so, when we click on any of the menu items, actually a form submission takes place and struts will interfere with it.

2. While creating parameter fields, make sure you do the following field.setReportName(”");
Though, it does not make any sense to set the reportName to blank string, it is a must, else the parameters will not be passed to the report. If inside the report you try to access these parameters, then Crystal Reports will throw the following exception and redirect you to a page, which asks for the missing parameters.
05 Feb 2005 16:17:01 [http80-Processor25] ERROR com.crystaldecisions.reports.formatter.formatter.objectformatter - com.crystaldecisions.reports.dataengine.al: Some parameters are missing values
05 Feb 2005 16:17:01 [http80-Processor25] ERROR com.crystaldecisions.reports.reportengineinterface - Error formatting page
com.crystaldecisions.reports.formatter.formatter.c: Some parameters are missing values
at com.crystaldecisions.reports.formatter.formatter.objectformatter.bf.<init>(Unknown Source)
at com.crystaldecisions.reports.formatter.formatter.objectformatter.bf.a(Unknown Source)
at com.crystaldecisions.reports.formatter.formatter.d.j.<init>(Unknown Source)
at com.crystaldecisions.reports.formatter.formatter.d.j.if(Unknown Source)
at com.crystaldecisions.reports.reportengineinterface.Engine.getPage(Unknown Source)
at com.crystaldecisions.reports.reportengineinterface.JPEReportSource.getPage(Unknown Source)
at com.crystaldecisions.report.web.viewer.ReportAgent.a(Unknown Source)
at com.crystaldecisions.report.web.viewer.CrystalReportViewer.goto(Unknown Source)
at com.crystaldecisions.report.web.ServerControl.a(Unknown Source)
at com.crystaldecisions.report.web.ServerControl.getHtmlContent(Unknown Source)
at com.thoughtworks.clearinghouse.web.servlet.GenerateSummaryReportAction.actionExecuted(GenerateSummaryReportAction.java:51)
at com.thoughtworks.clearinghouse.web.servlet.AbstractAction.execute(AbstractAction.java:40)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:437)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:264)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1109)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:470)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:763)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:284)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:204)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:245)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:199)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:195)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:164)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:149)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:156)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:972)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:211)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:805)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:696)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:605)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:677)
at java.lang.Thread.run(Thread.java:534)
Caused by: com.crystaldecisions.reports.dataengine.al: Some parameters are missing values
at com.crystaldecisions.reports.dataengine.a0.a(Unknown Source)
… 42 more
Even after setting reportName to blank string, we still get this error, but the values are passed correctly to the report.

Does someone have a solution, how to get rid of this exception?

Art of amazing object programming!

Monday, February 7th, 2005

public class ReportServerControl extends ServerControl {
private static final String ag = "RptVwSt";
private static final String N = "SelectionFormula";
private static final String R = "VTSelectionFormula";
protected static final String B = "ActionParams";
private static final String ak = "RptSrc_Chgd";
private static final String aj = "ActionNavigateTo";
private static final String G = "uri";
private static final String al = "DataContext";
private static final String X = "ObjectName";
private static final String A = "PendingEvent";
private static final String aa = "UserParams";
private static final String J = "UserLogons";
private static final String D = "TriedServerCap";
private static final String Z = "ServerCaps";
protected static final String Y = "ExportFormats";
private boolean ab;
private boolean T;
private boolean C;
private boolean x;
private ReportAgentBase am;
protected static final double L = 9.0;
private static double V;
private Hashtable H;
private static Object S;
private String O;
private Hashtable ah;
private Hashtable P;
private boolean an;
private String K;
private String F;
private String M;
private String af;
private boolean U;
private boolean y;
private Fields I;
private ConnectionInfos Q;
private boolean ae;
private boolean z;
private boolean ac;
private boolean W;
private boolean ai;
private PropertyBag E;
private static int ad;

public ReportServerControl() { }

protected void a(String batchId, Object other) { }

public void addReportPartBookmarkNavigationEventListener(IReportPartBookmarkNavigationEventListener iReportPartBookmarkNavigationEventListener) throws TooManyListenersException { }

public void addReportSourceChangeEventListener(ReportSourceChangeEventListener reportSourceChangeEventListener) { }

private void C() { }

protected ReportAgentBase x() { }

public void dispose() { }

void a(ReportPartBookmarkNavigationEventArgs reportPartBookmarkNavigationEventArgs) { }

protected Hashtable m() { }

public ConnectionInfos getDatabaseLogonInfos() throws ReportSDKExceptionBase { }

public Object getEnterpriseLogon() { }

protected String a(Exception e) { }

protected Hashtable s() { }

protected String z() { }

public Fields getParameterFields() throws ReportSDKExceptionBase { }

private String u() throws ReportSDKExceptionBase { }

private String l() throws ReportSDKExceptionBase { }

private String t() throws ReportSDKExceptionBase { }

protected Hashtable B() { }

protected ReportAgentBase o() { }

public IReportSource getReportSource() throws ReportSDKExceptionBase { }

public String getReportSourceClassFactoryName() { }

public String getSelectionFormula() throws ReportSDKExceptionBase { }

protected void a() { }

protected PropertyBag v() { }

double y() { }

private synchronized void w() { }

public String getStyleSheetFileName() { }

protected void a(String batchId) throws ReportSDKExceptionBase { }

private void p() throws ReportSDKExceptionBase { }

protected void a(ReportSDKException e) throws ReportSDKExceptionBase { }

protected void a(ReportSDKException e, String batchId) throws ReportSDKExceptionBase { }

private void a(ReportSDKException e, String batchId, boolean b) throws ReportSDKExceptionBase { }

public boolean isEnableLogonPrompt() { }

public boolean isEnableParameterPrompt() { }

protected boolean F() { }

protected boolean q() { }

boolean A() { }

public boolean isReuseParameterValuesOnRefresh() { }

protected void a(Object other) throws ReportSDKExceptionBase { }

public void navigateTo(String batchId, String batchId1) { }

private void a(String batchId, String batchId1, String batchId2) throws ReportSDKExceptionBase { }

protected void a(String batchId, String batchId1, String batchId2, boolean[] booleans) throws ReportSDKExceptionBase { }

protected void d() { }

private void E() throws ReportSDKExceptionBase, UnsupportedEncodingException { }

private void r() throws ReportSDKExceptionBase, UnsupportedEncodingException { }

public void refresh() { }

protected void D() throws ReportSDKExceptionBase { }

public void removeReportPartBookmarkNavigationEventListener() { }

public void removeReportPartBookmarkNavigationEventListenerr() { }

public void removeReportSourceChangeEventListener() { }

protected void a(Writer writer) throws IOException, ReportSDKExceptionBase { }

protected Object c() throws ReportSDKExceptionBase { }

public void setDatabaseLogonInfos(ConnectionInfos connectionInfos) { }

protected void a(ConnectionInfos connectionInfos) { }

public void setEnableLogonPrompt(boolean b) { }

public void setEnableParameterPrompt(boolean b) { }

public void setEnterpriseLogon(Object other) { }

public void setParameterFields(Fields fields) { }

protected void a(Fields fields) { }

protected void a(ReportAgentBase reportAgentBase) { }

public void setReportSource(Object other) throws ReportSDKExceptionBase { }

public void setReportSourceClassFactoryName(String batchId) { }

public void setReuseParameterValuesOnRefresh(boolean b) { }

public void setSelectionFormula(String batchId) { }

public void setStyleSheetFileName(String batchId) { }

public void setURI(String batchId) { }

public void setViewTimeSelectionFormula(String batchId) { }

protected void a(Writer writer, DeviceAdaptor deviceAdaptor) throws IOException { }

protected void a(InputStream inputStream) throws ReportSDKException { }

private String n() { }
}

No prizes for guessing it’s project right.

eXtreme Programming (XP) 2nd edition

Monday, February 7th, 2005

As XP is catching pace, the 12 practices of XP have grown to 25…26…(whatever). Though the basic principles and core XP values remain the same, the practices have been made more prescriptive. My understanding is that this is done to remove the so-called “ambiguity” with XP.

XP 1st edition Practices:

  • The Planning Game formalizes the rituals and roles of planning and estimations
  • Small Release tries to put a simple system into production quickly and then release versions on very short cycles
  • System Metaphor: how we communicate the system to others and ourselves
  • Unit Tests ensure that we don’t break one another’s code;
  • Simple Design - The system should be designed as simply as possible at any given moment. Extra complexity is removed as sson as it’s discovered
  • Refactor Mercilessly keeps the code clean and speeds progress;
  • Pair Programming gives higher quality, great cross-training, and higher speed;
  • Collective Owenership: Any one can change any code anywhere in the system at any time
  • Continuous Integration helps avoid Integration Hell;
  • 40 Hour week
  • An OnsiteCustomer to make sure we build business value;
  • Coding Standards

XP 2nd edition Practices:

  • DoTheSimplestThingThatCouldPossiblyWork encourages us not to over (or under)-engineer;
  • AskTheCode because it knows; CodeSmells if it has a problem; ListenToTheCode;
  • AcceptanceTests (formerly called FunctionalTests) tell us how we’re progressing against user needs;
  • ContinuousIntegrationRelentlessTesting helps avoid IntegrationHell;
  • SpikeSolution helps explore the area we’re working on;
  • ModelFirst plus SpartanUserInterface helps us concentrate on real customer value
  • ExtremePlanning suggests quickly building a map of the whole imagined system and incrementally refining it
  • CountDownToRelease discusses how to use the ExtremePlanning practices when you’re getting close to release
  • ExtremeReuse - adopting third party software and making it XP-compatible by building tests
  • TossIt - making projects trim and keeping projects trim
  • XpSimplicityRules
  • OnceAndOnlyOnce
  • ExtremeDocuments - we do documentation, sometimes differently
  • SupportCrisis - what to do until the doctor comes
  • IncrementalDelivery
  • LazyOptimization and EarlyProfiling
  • OpenWorkspace

Changes:
40-Hour week and Coding Standards seem to be dropped.

Overall, the core values of XP are what you need to understand when practicing XP. You don’t want to miss the forest for a tree. Don’t you?

Disclaimer: The new XP practices are the summary of what I read from the C2 Wiki. Thanks to Owen for letting me know that they are quite different from what’s in Kent Beck’s book.

How Tomcat Windows Service can ruin your weekend!

Monday, February 7th, 2005

Context: We are currently using Tomcat 5.0.19. Since we use ANT script to do all the project setup, tomcat is installed from the zip distribution. Once we unzip the tomcat installation zip (that’s the installation process), we use a separate bat file to install tomcat as a windows service. Following is the bat file contents.

@echo off
if "%OS%" == "Windows_NT" setlocal
rem ---------------------------------------------------------------------------
rem NT Service Install/Uninstall script
rem
rem Options
rem install Install the service using Tomcat5 as service name.
rem Service is installed using default settings.
rem remove Remove the service from the System.
rem
rem name (optional) If the second argument is present it is considered
rem to be new service name
rem CATALINA_HOME <Root_Dir>\Tomcat
rem JAVA_HOME E:\jdk_1.3.0
rem JRE Type hotspot
rem
rem ---------------------------------------------------------------------------

rem Guess CATALINA_HOME if not defined
set CURRENT_DIR=%cd%
set CATALINA_HOME=%3
if exist "%CATALINA_HOME%\bin\tomcat.exe" goto okHome
:gotHome
echo The tomcat.exe was not found...
echo The CATALINA_HOME environment variable is not defined correctly.
echo This environment variable is needed to run this program
goto end
:okHome

set EXECUTABLE=%CATALINA_HOME%\bin\tomcat.exe

rem Set default Service name
set SERVICE_NAME=TomcatClearinghousePortal

if "%1" == "" goto displayUsage
if "%2" == "" goto setServiceName
if "%3" == "" goto displayUsage
if "%4" == "" goto displayUsage
if "%5" == "" goto displayUsage
set SERVICE_NAME=%2
:setServiceName
if %1 == install goto doInstall
if %1 == remove goto doRemove
echo Unknown parameter "%1"
:displayUsage
echo
echo Usage: service.bat install/remove [service_name] CATALINA_HOME JDK_HOME JRE_TYPE
goto end

:doRemove
rem Remove the service
“%EXECUTABLE%” //DS//%SERVICE_NAME%
echo The service ‘%SERVICE_NAME%’ has been removed
goto end

:doInstall
rem Install the service
%EXECUTABLE% //IS//%SERVICE_NAME% –DisplayName “%2″ –Description “Indemand Clearinghouse Portal”
%EXECUTABLE% //US//%SERVICE_NAME% –Install %EXECUTABLE%
%EXECUTABLE% //US//%SERVICE_NAME% –ImagePath “%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\bin\bootstrap.jar”
%EXECUTABLE% //US//%SERVICE_NAME% –Java “%4\jre\bin\%5\jvm.dll”
%EXECUTABLE% //US//%SERVICE_NAME% –StartupClass org.apache.catalina.startup.Bootstrap;main;start –ShutdownClass org.apache.catalina.startup.Bootstrap;main;stop –Startup auto
rem Set extra parameters
%EXECUTABLE% //US//%SERVICE_NAME% –JavaOptions -Dcatalina.home=”"%CATALINA_HOME%”"#-Djava.endorsed.dirs=”"%CATALINA_HOME%\common\endorsed”"#-Djava.io.tmpdir=”"%CATALINA_HOME%\temp”"#-Xms32m#-Xmx256m#-Xrs
%EXECUTABLE% //US//%SERVICE_NAME% –StdOutputFile “%CATALINA_HOME%\logs\stdout.log”
%EXECUTABLE% //US//%SERVICE_NAME% –StdErrorFile “%CATALINA_HOME%\logs\stderr.log”
%EXECUTABLE% //US//%SERVICE_NAME% –WorkingPath “%CATALINA_HOME%\bin”
echo The service ‘%SERVICE_NAME%’ has been installed

:end
cd %CURRENT_DIR%

This will install Tomcat as a windows service and works fine.

Symptoms: Recently we had some issues integrating Tomcat with some other java service. When we started tomcat from the command prompt, everything worked fine. But as soon as we started tomcat as windows service, we’re left counting stars. Then we started searching for any error messages in the Tomcat log. Surprisingly we found that, though tomcat was writing logs, there was nothing related to our web application. We tried to reinstall the tomcat service but still no log messages.

Call the doctor: At this stage we felt that we should call the doctor. Guess who? Chris Stevenson. He’s saved us before in similar windows services related issues. Chris suggested that there’s an issue with the script that we are using to install Tomcat as a windows service. This is not the standard script that comes with the tomcat installation.

%EXECUTABLE% //IS//%SERVICE_NAME% --DisplayName "%2" --Description "Indemand Clearinghouse Portal"
%EXECUTABLE% //US//%SERVICE_NAME% --Install %EXECUTABLE%
%EXECUTABLE% //US//%SERVICE_NAME% --ImagePath "%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\bin\bootstrap.jar"
%EXECUTABLE% //US//%SERVICE_NAME% --Java "%4\jre\bin\%5\jvm.dll"
%EXECUTABLE% //US//%SERVICE_NAME% --StartupClass org.apache.catalina.startup.Bootstrap;main;start --ShutdownClass org.apache.catalina.startup.Bootstrap;main;stop --Startup auto
rem Set extra parameters
%EXECUTABLE% //US//%SERVICE_NAME% --JavaOptions -Dcatalina.home=""%CATALINA_HOME%""#-Djava.endorsed.dirs=""%CATALINA_HOME%\common\endorsed""#-Djava.io.tmpdir=""%CATALINA_HOME%\temp""#-Xms32m#-Xmx256m#-Xrs
%EXECUTABLE% //US//%SERVICE_NAME% --StdOutputFile "%CATALINA_HOME%\logs\stdout.log"
%EXECUTABLE% //US//%SERVICE_NAME% --StdErrorFile "%CATALINA_HOME%\logs\stderr.log"
%EXECUTABLE% //US//%SERVICE_NAME% --WorkingPath "%CATALINA_HOME%\bin"

Can you smell some thing fishy?
We are installing the service once and then updating the service 8 times. After trying out different things for some time, we accidentally discovered the issue. Guess what?

%EXECUTABLE% //US//%SERVICE_NAME% --JavaOptions -Dcatalina.home=""%CATALINA_HOME%""#-Djava.endorsed.dirs=""%CATALINA_HOME%\common\endorsed""#-Djava.io.tmpdir=""%CATALINA_HOME%\temp""#-Xms32m#-Xmx256m#-Xrs

This line was the culprit. But as anyone would guess, it’s not the weird looking #. But it’s the tmpDir, that’s the culprit. When we checked, we didn’t have a temp dir under CATALINA_HOME. As soon as we created the temp folder, everything started working fine.

Root Cause: When tomcat is started as a service, it does not create any folders. If the temp folder is not present, it will behave strangely. Most of the things would work fine, but occasionally you might find some issues.

Lesson learnt: If tomcat is acting weird, check the logs, if the logs are not correct then there has to be some issue with the service installation script. Make sure that all the folders referred in the script are actually present.

    Licensed under
Creative Commons License
Design by vikivix