Tuesday, April 14, 2009

Crystal Reports IllegalStateException

So, my companies web app was throwing this nebulous IllegalStateException exception (see stacktrace below) that did not seem to adversely affect the application but I just couldn't let it go. I was able to resolve it like this:
  1. First, I googled it... not much help in the first few pages other than telling me what I already knew. 'out' was being called after it had been commited/closed.
  2. Though I usually don't have to do this anymore, it finally dawned on me to look at the compiled JSP code. (This was legacy, pure JSP... no struts nor nothing.) We were using Tomcat 5.5 and Eclipse 3.3+ so my JSP class was in the 'work' directory of my Eclipse project. Sure enough, there were out.print("") in my compiled JSP class. Where were they coming from?
  3. We had no explicit out.print() in our JSP code, so just looking at where they were in the class and how our JSPs were constructed, it seemed a close correspondence to an out reference for every JSP directive (like @page, etc.)
  4. So, I googled this: illegalstateexception crystal tomcat
    and came across this link http://www.forumtopics.com/busobj/viewtopic.php?t=126993&sid=2b09528912043e0fbe72e0a947dc300a which basically tells you to avoid line breaks between your JSP directives.
  5. Problem solved.

|ESD|13:28:22,363|ERROR|Servlet.service() for servlet jsp threw exception [http-12080-Processor22|org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/esd].[jsp]]
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:607)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:196)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:179)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:116)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:76)
at org.apache.jsp.pages.reports.CrystalReportViewer_jsp._jspService(CrystalReportViewer_jsp.java:184)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:875)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
at java.lang.Thread.run(Thread.java:595)

Wednesday, April 8, 2009

Script your ODBC Data Sources (MySQL)

Ok... admittedly this has to do with Windows scripting and not Java nor Javascript but is something that affects many of my projects. If your computer needs ODBC Data Sources, you can script their creation (particularly useful for configuring new developers' computers).

This script should provide a fairly useful start to customizing your own version. I am going to assume that it is fairly self-explanatory but you can always post a response if you do not agree or have a question.

' This script creates one or more ODBC Data Sources.

' Usage: >cscript crystal.odbc.test.vbs
' Notes:
' * Search for 'configure-here' for all customization options
Const HKEY_LOCAL_MACHINE = &H80000002

strPrefix = "winmgmts:{impersonationLevel=impersonate}!\\"
strComputer = "."
strSuffix = "\root\default:StdRegProv"
strObjRef = strPrefix & strComputer & strSuffix ': wscript.echo strObjRef
Set objReg = GetObject(strObjRef) 'The Set keyword is mandatory

DriverNames = Array("SQL Server", "MySQL ODBC 3.51 Driver") 'Generally, do not modify these
Drivers = Array("C:\WINDOWS\System32\SQLSRV32.dll", "C:\WINDOWS\system32\myodbc3.dll") 'Generally, do not modify these
' Configuration Section
Const Chosen = 1 'configure-here: Zero-based index into the following two arrays; i.e. which DB are you using
Const Server = "xxxwebtest" 'configure-here: the machine where the DB is hosted
Const Port = "3307" 'configure-here: the port where the DB is hosted
Const Uid = "root" 'configure-here: the username to the DB
Const Pwd = "admin" 'configure-here: the password to the DB
ConnectionList = Array("dbone", "dbtwo", "etcetera") 'configure-here: see Note 1 below

REM *** Note 1 *** This is the array of ODBC Names which you will be creating;
REM also is the name of the database which the odbc connects to
'=== End : Configuration Section ================================

for each connection in ConnectionList
wscript.echo "*** Start *** Creating ODBC Data Source: " & connection

' *** Step 1 *** Create new Data Source Entry in system folder ...\ODBC Data Sources
strKeyPath = "SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources"
strValueName = connection
strValue = DriverNames(Chosen)
call WriteToRegistry

' *** Step 2 *** Create Data Source configuration in new user-defined folder {connection}
strKeyPath = "SOFTWARE\ODBC\ODBC.INI\" & connection
objReg.CreateKey HKEY_LOCAL_MACHINE,strKeyPath

' *** Step 2a *** Database
strValueName = "DATABASE"
strValue = connection
call WriteToRegistry

' *** Step 2b *** Driver
strValueName = "DRIVER"
strValue = Drivers(Chosen)
call WriteToRegistry

' *** Step 2c *** Server
strValueName = "SERVER"
strValue = Server
call WriteToRegistry

' *** Step 2d *** Port
strValueName = "PORT"
strValue = Port
call WriteToRegistry

' *** Step 2e *** UID
strValueName = "UID"
strValue = Uid
call WriteToRegistry

' *** Step 2f *** PWD
strValueName = "PWD"
strValue = Pwd
call WriteToRegistry

' *** Step 2g *** Trusted_Connection : SQL Server only?
strValueName = "Trusted_Connection"
strValue = "Yes"
' call WriteToRegistry

' *** Step 2h *** Description
strValueName = "DESCRIPTION"
strValue = "EditMeThroughRegEdit"
call WriteToRegistry

wscript.echo "*** Finished *** Creating ODBC Data Source.\n"
next 'connection
'===== End of Script =====

' Subroutines and Functions
Sub WriteToRegistry
Const debugDesired = false
If debugDesired Then
wscript.echo "Simulating name/value to: HKEY_LOCAL_MACHINE\" & strKeyPath & ": " & strValueName & "/" & strValue
wscript.echo "Modifying name/value to: HKEY_LOCAL_MACHINE\" & strKeyPath & ": " & strValueName & "/" & strValue
objReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
End If
End Sub