Tuesday, December 12, 2006

According to TLD or attribute directive in tag file, attribute value does not accept any expressions

Keywords:
Compile JSP tomcat JSTL error "According to TLD or attribute directive in tag file, attribute value does not accept any expressions"

Problem:
Compile error from tomcat when it encounters a JSP: "According to TLD or attribute directive in tag file, attribute value does not accept any expressions"

Solution:
For some reason the JSP is using the 1.2 JSP (and 1.0 JSTL) and EL expressions aren't understood. There's a lot of hits on the web for this but in summary there are 2 important things to do to ensure you're getting the right version of the spec:
  1. Reference the correct servlet specification in your deployment descriptor:
    <?xml version="1.0"?>
    <web-app version="2.4"
     xmlns="http://java.sun.com/xml/ns/j2ee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  2. Reference the correct JSTL uri in your JSP:
    change
    <%@ taglib uri='http://java.sun.com/jstl/core' prefix='c'%>

    to
    <%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>

Notes:


What Specification goes with what?
Web-app(deployment schema)2.32.42.5
http://java.sun.com/dtd/web-app_2_3.dtdhttp://java.sun.com/xml/ns/j2ee/web-app_2_4.xsdhttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd
Servlet2.32.42.5
JSP1.22.02.1
JSTL(core uri reference)1.01.11.2
http://java.sun.com/jstl/corehttp://java.sun.com/jsp/jstl/corehttp://java.sun.com/jsp/jstl/core
Tomcat4.x5.x6.x
WebSphere5.x6.x7.x (?)

Friday, December 08, 2006

WebSphere DTMConfigurationException: No default implementation found

Keywords:
WebSphere DTMConfigurationException DTMManager xalan 6.0.2.11

Problem:After upgrading the WebSphere Application Server JDK with the .11 Fix pack (making it 6.0.2.11) there is the following error when my web app. tries to get a transformer:
org.apache.xml.dtm.DTMConfigurationException: No default implementation found
    at org.apache.xml.dtm.DTMManager.newInstance(DTMManager.java:177)
    at org.apache.xpath.XPathContext.(XPathContext.java:125)
    at org.apache.xalan.transformer.TransformerImpl.(TransformerImpl.java:398)
    at org.apache.xalan.templates.StylesheetRoot.newTransformer(StylesheetRoot.java:197)

Solution:
The problem seems to be at least associated with the fix pack creating a new file "xalan.properties" in APPSERVER_HOME\java\jre\lib. It could also be upgrading the xalan libraries as well (in xml.jar).

Edit this file - you'll notice this isn't defining any properties, everything is commented out - and add the property:
org.apache.xml.dtm.DTMManager=org.apache.xml.dtm.ref.DTMManagerDefault


Notes:
Alternatively, remove or rename this file and the problem should also go away.

Alternatively again, add the JVM system property "org.apache.xml.dtm.DTMManager". You can do this on WebSphere by going to:
Application servers > server1 > Process Definition > Java Virtual Machine
... and adding to the Generic JVM arguments:
-Dorg.apache.xml.dtm.DTMManager=org.apache.xml.dtm.ref.DTMManagerDefault

Restart the server and the problem should also go away - use this approach for where you don't have access to the APPSERVER_HOME\java\jre\lib files and can only configure your application's JVM.

Wednesday, November 15, 2006

IIS not streaming PDF

Keywords:
IIS 6.0 not streaming PDF IE

Problem:
As is the theme for many of these posts. The setup is IIS -> ISAPI/JK -> Tomcat. The application running on Tomcat is generating PDF. If you access the application directly via Tomcat the PDF content is returned fine - ie. Opens via the Adobe Reader plugin in IE. If you access the application via IIS you get a blank page in IE. All other formats work fine.

Solution:
The problem in this case was a setting in IIS that zips the content it's serving up. This is fine for HTML as browsers recognise this and unzip. For the Adobe PDF reader, the content is not expected to be compressed - hence the blank page, it doesn't know what to do (but an error message would have helped).

In IIS Manager, right click on the folder "Web Sites" and choose Properties. Click the "Services" tab.

You need to make sure HTML Compression is turned off. I’m not sure about the IIS 5.0 isolation setting ...

Restart IIS – right click the server (above the Web Sites folder) and choose All Tasks > Restart IIS ...

Select the "Restart Internet Services on YOUR-SERVER" option. It will only take only a few seconds (rather than 300).

Tuesday, November 14, 2006

Can't start IIS "World Wide Web Publishing Service" Error 126

Keywords:
Could not start IIS "World Wide Web Publishing Service" "Error 126"

Problem:
Trying to manually start the WWW service for IIS gives the following message:
"ERROR 126: The specified module could not be found."

The "World Wide Web Publishing Service" goes back to a stopped status. While this service is stopped, in the IIS Manager, the Web Sites folder is marked with an X and none of the Web Sites can be started.

Solution:
Need to check the Event Logs (Start > Programs > Administrative Tools > Event Viewer)

Clicking on the Application section shows a number of Errors. The most recent two errors were the most relevant:
  • Could not load all ISAPI filters for site/service. Therefore startup aborted.

  • The HTTP Filter DLL C:\[path to a DLL that no longer exists] failed to load. The data is the error.
I had to go into IIS Manager. View the ISAPI Filters (right click the Web Sites Folder > Properties > ISAPI Filters) and remove the filter that was referencing this DLL.

Going back to services, the WWW Publishing Service then starts fine.

Wednesday, November 08, 2006

spring webflow 1.0 build fails

Keywords:
spring webflow 1.0 build sample

Problem:
Downloaded the latest spring webflow distribution (1.0) and trying to build (just a sample app. in this case) causes NoClassDefFoundError errors ... but surely this is shipped with the right libraries?

ivy.configure:
[echo] reading ivy config
[ivy:configure] :: Ivy 1.4 - 20061009124215 :: http://ivy.jayasoft.org/ ::

BUILD FAILED
java.lang.NoClassDefFoundError: org/apache/commons/httpclient/UsernamePasswordCredentials


Solution:
It's not enough to make sure you have Java 1.5+ and Ant 1.6+ ... these must also not have different versions of the dependent libraries.

In my case, there was an different version of apache commons-httpclient in the ant/lib folder ... removing this from the /lib folder or pointing at a 'clean' version of Ant resolves the issue.

Friday, November 03, 2006

java.io.FileNotFoundException spring-beans_2_0.dtd

Keywords:
java.io.FileNotFoundException spring-beans_2_0.dtd spring java 2.0 MVC

Problem:
Following the guide (such as the "Spring Framework MVC application step-by-step") and you get this error about the DTD reference in the -servlet.xml file.

Solution:
This is an easy one, the file seems to have been renamed ... the DTD is actually accessed from the web. Change the _2_0 to -2.0

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans_2_0.dtd">


<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

Wednesday, September 13, 2006

vmware "parent of this virtual disk could not be opened"

Keywords:
vmware "parent of this virtual disk could not be opened" moved windows linux

Problem:
Moved a Virtual Machine setup (Windows 2003 Server RC2) that was created on a machine running Windows (2003 server) to a Linux machine (RedHat Enterprise 4) and get the following error when you try to view the the disk properties or start the Virtual Machine:

... "parent of this virtual disk could not be opened" ...

Solution:
If you've taken a snapshot for this VM in the past there will be a text file with a name like: "Windows Server 2003 Standard Edition-000001.vmdk". Stupidly, this contains a full path reference to the location of the "parent file" (which by default will be in the same folder). This has to be changed if you move the VM to another host machine.

Below is what this file looked like ... simply remove the full path reference, save the file and try again.

# Disk DescriptorFile
version=1
CID=e615c3de
parentCID=67e1d188
createType="twoGbMaxExtentSparse"
parentFileNameHint="c:\virtual machines\test-server\Windows Server 2003 Standard Edition.vmdk"
# Extent description
RW 4192256 SPARSE "Windows Server 2003 Standard Edition-000001-s001.vmdk"
RW 4192256 SPARSE "Windows Server 2003 Standard Edition-000001-s002.vmdk"
RW 4192256 SPARSE "Windows Server 2003 Standard Edition-000001-s003.vmdk"
RW 4192256 SPARSE "Windows Server 2003 Standard Edition-000001-s004.vmdk"
RW 8192 SPARSE "Windows Server 2003 Standard Edition-000001-s005.vmdk"

# The Disk Data Base
#DDB

Wednesday, July 26, 2006

Slide 2.1 working with Security on WebSphere 6.0.2.11

Keywords:
slide 2.1 security websphere 6.0.2.11
Problem:
Slide 2.1 does not work "out-of-the-box" with WebSphere 6. It seems most slide-users have worked around it by turning off security. Clearly, this is not an option for a production system - so we need to get it working.
Solution:
This is a elaboration on my post #12099 to the slide-user list. Thanks to the post on the list from Lynn Richards #10690. A committer is welcome to add any content from here to the Slide-Wiki on WebSphere Setup. It certainly needs more detail. You will need:
  • slide-server-2.1 source code - in order to make corrections and re-build.

  • IBM HTTP Server (IHS) and the Web Server Plugin

Slide Source Changes - UTF-8

There are a two places (that I could find) in the code where the content type is set to "text/xml; charset=\"UTF-8\"". The WebSphere servlet container can't handle the quotes around the encoding. This needs to be changed to "text/xml; charset=UTF-8". This works for Tomcat too, so perhaps it should be committed in the server source?
  1. jakarta-slide-server-src-2.1\src\webdav\server\org\apache\slide\webdav\method\AbstractWebdavMethod.java
    128c128
    < public static final String TEXT_XML_UTF_8 = "text/xml; charset=\"UTF-8\"";
    ---
    > public static final String TEXT_XML_UTF_8 = "text/xml; charset=UTF-8";
  2. jakarta-slide-server-src-2.1\src\webdav\server\org\apache\slide\webdav\util\DirectoryIndexGenerator.java
    145c145
    
    <         res.setContentType("text/html; charset=\"UTF-8\"");
    ---
    >         res.setContentType("text/html; charset=UTF-8");

Slide Configuration

"/" Path "Forbidden"

The issue where all paths appear to be "/" no matter what path is accessed on Slide is due to the following code in jakarta-slide-server-src-2.1-\src\webdav\server\org\apache\slide\webdav\util\WebdavUtils.java and a difference in implementation between WebSphere and Tomcat
    String result = null;
  if (config.isDefaultServlet()) {
      result = req.getServletPath();
  } else {
      result = req.getPathInfo();
  }
req.getServletPath() seems to always be "/" in WebSphere when the WebDAV servlet is mapped to "/". The solution is to force slide to use the getPathInfo() method by turning off the Default Servlet flag in the web.xml:
 <param-name>default-servlet</param-name>
<param-value>false</param-value>

The EAR file might be corrupt? web.xml validation

When you install a war file on WebSphere the web.xml is parsed and validated against the spec. Any discrepancies with the spec will give you the un-helpful error that the "EAR file might be corrupt". Add the detail below to you opening node in the web.xml and make sure it is valid according to the schema (using an editor such as XML Spy) before including it in the war file:
<web-app
 version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee";
 xsi="http://www.w3.org/2001/XMLSchema-instance"
 schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
You'll find that all the <description> nodes are in the wrong place within the <init-param> nodes - they should be the first child rather than the last.
More importantly is the security-constraint section. To get authentication, you must define the constraint for all the possible http (WebDAV) methods. The problem is according to the web.xml spec, the only valid http-method values are: HEAD, GET, POST, PUT, DELETE, OPTIONS and TRACE. To have the other WebDAV methods secure as well, leave the specific http-method constraints out. This node is optional and if you don't specify any, all Http methods will be secure and this will include the WebDAV extensions too.
 <!-- Uncomment this to get authentication -->
<security-constraint>
  <web-resource-collection>
      <web-resource-name>DAV resource</web-resource-name>
      <url-pattern>/*</url-pattern>
      <!-- comment out the explicit http-method list                     
   'valid' Http Methods
         <http-method>GET</http-method>
         <http-method>HEAD</http-method>
         <http-method>OPTIONS</http-method>
         <http-method>POST</http-method>
         <http-method>PUT</http-method>
         <http-method>DELETE</http-method>
         Http Extensions
         <http-method>COPY</http-method>
         <http-method>LOCK</http-method>
         <http-method>MKCOL</http-method>
         <http-method>MOVE</http-method>
         <http-method>PROPFIND</http-method>
         <http-method>PROPPATCH</http-method>
         <http-method>UNLOCK</http-method>
         <http-method>VERSION-CONTROL</http-method>
         <http-method>REPORT</http-method>
         <http-method>CHECKIN</http-method>
         <http-method>CHECKOUT</http-method>
         <http-method>UNCHECKOUT</http-method>
         <http-method>MKWORKSPACE</http-method>
         <http-method>UPDATE</http-method>
         <http-method>LABEL</http-method>
         <http-method>MERGE</http-method>
         <http-method>BASELINE-CONTROL</http-method>
         <http-method>MKACTIVITY</http-method>
         <http-method>ACL</http-method>
         <http-method>SEARCH</http-method>
         <http-method>BIND</http-method>
         <http-method>UNBIND</http-method>
         <http-method>REBIND</http-method>
         <http-method>SUBSCRIBE</http-method>
         <http-method>UNSUBSCRIBE</http-method>
         <http-method>POLL</http-method>
         <http-method>NOTIFY</http-method>
  -->
  </web-resource-collection>
  <auth-constraint>
      <role-name>SlideAdmin</role-name>
      <role-name>User</role-name>
  </auth-constraint>
</security-constraint>

WebSphere Configuration

Global Security

How to configure WebSphere with a Custom or LDAP realm is beyond the scope of this post (maybe later) but with Security turned on, you will need to either Turn off "Java 2 Security" or define a policy file for the slide web-app.
With Java 2 security on, slide will get AccessControlException(s) when it tries to check for the existence of things like its properties file (from the "java.home" location? See Configuration.java - it will catch the exception if the load fails but not if the file.exists() check is forbidden).

WebServer Integration

It appears that when the WebSphere AppServer handles HTTP requests it assumes the same default as the IBM WebServer, namely - content is only to be expected and read for POST and PUT requests. This page on IBM's support site is old but seems to apply for v6 as well: Software
Group Ref #1145705
.
To get the WebDAV extensions to HTTP working you need to configure the IBM WebServer with the AppServer using IBM's WebServer Plugin. It's in the Plugin where you're then able to allow content in all HTTP/WebDAV requests. Ie "true" for
AcceptAllContent
Specifies whether or not users can include content in POST, PUT, GET, and HEAD requests when a Content-Length or Transfer-encoding header is contained in the request header. You can specify one of the following values for this attribute:

  • true if content is to be expected and read for all requests
  • false if content only is only to be expected and read for POST and PUT requests.
false is the default.
If you have version 6, with the WebServer and AppServer on the same machine and the Server setup to propagate changes to the plugin-cfg.xml file, you can set this flag in the Admin Console:
  • Web servers > webserver1 > Plug-in properties > Request and response
    Check the box for - Accept content for all requests
I found integrating the AppServer with the WebServer via plugin not a simple process. You should do this before installing slide and use the /snoop servlet to check if things are working via the WebServer.

Aside: If you try a URL like: http://localhost/snoop/hello/world/ok you will see the difference between the ServletPath and PathInfo in WebSphere and why we need to force slide to use the later.
You could actually use a WebServer other than IBM's. The difference will be that you may need to manually configure the Plugin in the AppServer and WebServer and then when the Admin console updates the plugin-cfg.xml file you may need to copy this to the place where the WebServer expects.

Installing Slide

After you install/deploy the slide.war (I gave it the enterprise application name of "slide") you need to edit the Class Loading properties.
Class loader mode = Parent Last
WAR class loader policy = Application
This avoids the problem of WebSphere v6 including an older version of JDOM (1.0Beta7) in its lib folder as well as property file loading issues. Check that slide has been correctly associated with the WebServer Plugin:
  • Enterprise Applications > slide > Map modules to servers
    You should see something like:
    Server
    WebSphere:cell=wasNode01Cell,node=webserver1_node,server=webserver1
    WebSphere:cell=wasNode01Cell,node=wasNode01,server=server1
It's important to see both the server and the webserver "module" in this list.
After starting the slide application it should be accessible via the WebServer (port 80 by default). All access will have to be via the WebServer and this should hopefully work without error and will be secure.

Tuesday, July 18, 2006

AccessControlException access denied WebSphere

Keywords:
java.security.AccessControlException: access denied websphere

Problem:
After enabling global security in WebSphere, all access to file system resources from the web app gives "AccessControlException" messages. The application can't load it's properties file(s).

Solution:
I actually found this solution pretty quickly with a google search. Need to turn off "Java 2 Security" in the Global Security settings or define a policy that allows your application access to the resources it needs.

To disable "Java 2 Security"
  1. Open the administrative console and go to Security-->Gloabal Security
  2. Uncheck "Enforce Java 2 Security"
  3. Save the changes and restart WebSphere
To define a policy

Monday, July 17, 2006

Can't deploy WAR on WebSphere 6 - AppDeploymentException

Keywords:
websphere war deploy install "The EAR file might be corrupt or incomplete" DeploymentDescriptorLoadException

Problem:
Trying to deploy ("install") a war file (for the Jakarta Slide WebDAV Server) in WebSphere after it appeared to work fine on Tomcat & JBoss gets the following two messages in the WebSphere Administration Console:

  1. The EAR file might be corrupt or incomplete.

  2. AppDeploymentException: [null] com.ibm.etools.j2ee.commonarchivecore.exception.DeploymentDescriptorLoadException: IWAE0022E Exception occurred loading deployment descriptor for module "[warfilename].war" in EAR file "[WebSphereHome]\profiles\[ProfileName]\wstemp\[TempFolder]\upload\[warfilename]_war.ear"


Solution:
The first message (and the .ear part of the second) is very confusing and from a quick google it seems that many developers are thrown off and attempt to put their war file in an ear ... it's not necessary.

The clue was the cause exception "DeploymentDescriptorLoadException" in the second message. It's a long story how I got to this, but the issue was my deployment descriptor - WEB-INF\web.xml. WebSphere validates this against the schema for the web.xml and is not flexible. Add this detail to you opening <web-app> node in your web.xml and make sure it is valid according to the schema (using an editor such as XML Spy):
<web-app version="2.4" 
xmlns="http://java.sun.com/xml/ns/j2ee"   
xsi="http://www.w3.org/2001/XMLSchema-instance" 
schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">


In my situation slide contained a security-constraint which in turn referenced http-method names that aren't valid according to the web.xml spec (limited to HEAD, GET, POST, PUT, DELETE, OPTIONS, TRACE). But WebDAV extends the HTTP spec ... not sure what to do about that. Commenting out the entire security-constraint section or the offending http-method references fixes the issue for the mean time.


Notes:
Next issue is how to configure some basic users and roles in WebSphere. The documentation seems very thorough on overviews and definitions, but light-on when it comes to how-tos.

Tuesday, July 11, 2006

Cannot load mod_jk.so into server: The specified procedure could not be found

Keywords:
apache mod_jk mod_jk.so "The specified procedure could not be found" tomcat

Problem:
I've download the Apache HTTP server and according to the apache.org site "2.2.2 is the best available version". The downloaded mod_jk from the tomcat.apache.org where it claimed that the mod_jk-1.2.14-apache-2.0.54.so download was for Apache 2.0, and works with Apache 2.0.55 and later ... there was no 2.2.x download so I assumed (wrongly) that this would work with Apache 2.2.x as it is "later".

Added the LoadModule line in the httpd.conf file as instructed in http://tomcat.apache.org/connectors-doc/howto/apache.html
and got the following error:
Cannot load [full path]/mod_jk.so into server: The specified procedure could not be found


Solution:
You can't use a Apache 2.0.x module with Apache 2.2.x apparently - it must be built pointing at that specific version of Apache (if you're clever enough to build your own modules with the source code then this is no problem - you could get the source for JK 1.2.15 and build it pointing at your install Apache 2.2.x).

If you rely on the binaries built by Apache, use the HTTP server 2.0.x

Wednesday, July 05, 2006

xalan parameter must be a "valid Java Object"

Keywords:
xalan IllegalArgumentException "The value of param" "must be a valid Java Object"

Problem:
On an application server (JBoss) where you can't control the version of xalan that is getting loaded with your web application, you get the following error in the preparation phase of a XML transform:
java.lang.IllegalArgumentException: The value of param [param-name] must be a valid Java Object
at org.apache.xalan.transformer.TransformerImpl.setParameter(TransformerImpl.java:1587)

Solution:
The issue here is that the object being set in the javax.xml.transform.Transformer.setParameter(String name, Object) is a null. In xalan 2.5.0 this doesn't seem to be an issue, but in xalan 2.7.0 it is!

Stop the null being put set as a parameter and the issue is solved.


Notes:
The last few posts have been around this issue of the web application not being able to control its classpath in JBoss. I've tried the ClassLoadingConfiguration advice in the JBoss Wiki with no success. The endorsed directory contains the different xalan library (as visible in the "sun.boot.class.path" system property) and despite specifying some sort of isolation, the endorsed directory still applies. As the issue was ultimately with a newer version of xalan and it's probably be bad to be putting nulls in anyway I haven't tried to force this class/library loading issue.

Monday, July 03, 2006

Invalid or corrupt jarfile

Keywords:
"Invalid or corrupt jarfile" java -jar manifest file

Problem:
Packaging up a class with a main method into a jar-file using ant gives the following error when you try to run it with the java -jar [jarfile] command: "Invalid or corrupt jarfile".

Solution:
Using the ant task to create the manifest file on-the-fly gives you and entry like:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.2
Created-By: 1.4.2_07-b05 (Sun Microsystems Inc.)
Main-Class: com.example.MyMainClass


Creating the manifest file myself, with the bare essentials fixes the issue:
Manifest-Version: 1.0
Main-Class: com.example.MyMainClass



With more investigation I'm sure I could have got the dynamic meta-file creation working with Ant as I know other people do - there must be some peculiarity in the combination of my ant version (1.6.2), java version (1.4.2_07) and perhaps the current phase of the moon.


Notes:
Parsing of the Meta-inf file has been an issue that has come-up, been fixed and then come-up again for sun. See: Bug Id: 4991229. If you can work out if this bug exists in the your (or my) version of the Java SE you have more patience that me.

Tuesday, June 13, 2006

What version of xerces have I got?

Keywords:
xerces version print classpath parser

Problem:
This is kind of related to the previous two posts. With XML parsing + classpath issues it's often useful to know not only what version of Xerces you're using but also where it's been loaded from.

Solution:
This is based on the equivalently useful site of Java Almanac - Determining from Where a Class Was Loaded. The point they make about the system classloader is crucial: "It is not possible to determine the location of classes loaded by the system class loader in the same way since the class' code source is null."

If your Xerces is the one loaded by the system, then this may explain some unusual behaviour if your web application expects to ship with it's own version.

  public static String getXercesDetails() {
       // no hard-writed references to the version class because it might be unavailable
       Class c;
       Method m;
       Object obj;

       try {
           c = Class.forName("org.apache.xerces.impl.Version");
           m = c.getDeclaredMethod("getVersion", new Class[] {});
           if (Modifier.isStatic(m.getModifiers())) {
               // Xerces 2.x
               obj = null;
           } else {
               // Xerces 2.1.x
               obj = c.newInstance();
           }
          
           ProtectionDomain pDomain = c.getProtectionDomain();
           CodeSource cSource = pDomain.getCodeSource();
           String loc = "?";
           if (cSource != null) {
               loc = cSource.getLocation().toString();
           } else {
               // CodeSource is null, Xerces loaded by system class loaded.
               loc = "(system classloader? sun.boot.class.path = " + System.getProperty("sun.boot.class.path") + ")";
           }
          
           return ((String) m.invoke(obj, new Object[] {})) + " from " + loc;
       } catch (Exception e) {
           return "unkown (" + e.getMessage() + ")";
       }
   }


Notes:
Xerces (and Xalan) in the endorsed directory can cause some nasty issues for applications that expect to use their own version. See the JBoss Issue: JBAS-2073

Saturday, June 10, 2006

How do you print the java classpath?

Keywords:
java servlet "print classpath"

Problem:
This requirement came in trying to diagnose the previous post. It'd be quite useful in a any enterprise/web application to be able to see the classpath in use (perhaps via an administration page).

Solution:
This is based on post on Java Tips (very useful site), but with the difference that your web application will have a different classloader to the system one. You'll need the classloader being used by a class within the web application (such as the one responsible for producing your admin-output).

 public String getClasspathString() {
     StringBuffer classpath = new StringBuffer();
     ClassLoader applicationClassLoader = this.getClass().getClassLoader();
     if (applicationClassLoader == null) {
         applicationClassLoader = ClassLoader.getSystemClassLoader();
     }
     URL[] urls = ((URLClassLoader)applicationClassLoader).getURLs();
      for(int i=0; i < urls.length; i++) {
          classpath.append(urls[i].getFile()).append("\r\n");
      }    
     
      return classpath.toString();
  }

Friday, June 09, 2006

An invalid XML character (Unicode: 0x0) was found in the comment

Keywords:
xerces "An invalid XML character (Unicode: 0x0) was found in the comment"

Problem:
This is a very specific problem I admit, but what are you meant to do? From the error message list for the Xerces parser, it's clear that this "0x0" character is a bad thing, but it's also clear that I haven't put this character in the document.

Something's wrong with the reading/processing of the byte stream containing the XML content.

Solution:
A very specific solution too. In this case it was that file was being stored using a Slide implementation that came with JBoss. I don't know anything about this implementation, but it doesn't seem to work when you're accessing it (via WebDAV) with jakarta-slide-client libraries. Switching the storage to using the latest version from Jakarta fixed this issue.

Monday, April 10, 2006

shell script 'bad interpreter'

Keywords:
tomcat catalina.sh "bad interpreter" sh shell

Problem:
Can't execute the shell script on linux. Everything seems in fine. The environment variables required by the script, the $PATH and the script has user has execute permission on the script (chmod +x catalina.sh).

Error each time is
bad interpreter: No such file or directory

Solution:
DOS/Non-Ascii characters in the script! Not sure vi doesn't highlight this (as ^M for example) - it could be a quirk with that version of vi or the console being used (putty in this case).

The solution is simple:
dos2unix catalina.sh catalina.sh

Try again via:
./catalina.sh run

All works.

Monday, March 27, 2006

Property/Variable reference in log4j.properties

Keywords:
environment variable log4j.properties

Problem:
In your log4j.properties file a relative reference to a folder is fine as long as you start the program (eg tomcat) the same way from the same location every time.
Eg: log4j.appender.LOGGER.File=../logs/slide.log
(Ok if you're starting tomcat from CATALINA_HOME/bin/catalina.bat)

If not, you will get FileNotFound exceptions when the parent folder can't be found. In the above example, starting tomcat from a windows service will have the user.dir=C:\WINDOWS\SYSTEM32, so ../logs is C:\WINDOWS\logs & doesn't exist.

Solution:
Make explicit file references using system properties in the log4j.properties file. Note, you can not use environment variables (that's a platform specific concept).

System properties can be set in code or for this purpose should be set with the "-D" JVM option.

With the above tomcat example, most of the important environment variables to tomcat are copied into corresponding system properties if you use the standard scripts.
Eg: in catalina.bat: -Dcatalina.home=%CATALINA_HOME%

This allows you to reference the property using ${...} notation
Eg: log4j.appender.LOGGER.File=${catalina.home}/logs/slide.log

Sunday, March 26, 2006

Missing JAAS Config

Keywords:
"Unable to locate a login configuration" JAAS Tomcat

Problem:
Starting up tomcat as a service on Windows the above error message with stack trace displayed. The file it's referring to as missing is in the folder %CATALINA_HOME%/conf/jaas.config

Solution:
You need to make sure the system property "java.security.auth.login.config"
is defined & this should be a full path to the file. This can be via the -D JVM option. eg:
-Djava.security.auth.login.config=%CATALINA_BASE%\conf\jaas.config

Depending on whether you run tomcat via "catalina.bat" or the windows service will determine the best place to put this option.


Notes:
Ok, not a profound solution to start with but it's a solution with a problem description that will hopefully come up in a similar keyword search. I had to scroll to the 6th search result on http://www.google.com.au/search?hl=en&q=%22Unable+to+locate+a+login+configuration%22+JAAS+Tomcat
which actually isn't too bad.

Monday, March 20, 2006

Tired of googling questions with no answers

As a Developer/Architect, questions are almost an everyday part of life. Particularly working with Java and Open Source technologies; limited documentation, weird stack traces, unexpected behaviour typically lead me to the web for help. I'm not alone ...

The typical sequence of problem solving goes as follows:

  1. Putting question/error message/keywords in a web search.
  2. This will almost always find results - in the hundreds & thousands - great!
  3. Follow links to the search results and I'll find at least one if not dozens of descriptions of the exact same problem scenario.
  4. Scroll down, follow the links to posted comments/replies. I'll find heaps of people saying they have the same problem ... but no solution. If I'm really unlucky, I'll find the last comment from the original poster saying "Oh forget it, I've resolved the issue ... thanks".
  5. The wording/phrasing of someone's comment may lead me to thinking about my problem differently, inspire me to try something else and alleluia! The problem is solved and I move on the next one.

If I'm conscientious I'll note this in my trusty notebook for future reference. On the (very) rare occasion I'm feeling good will toward all people-kind I'll try to see if I can put at least my take on the solution on one of the websites I saw the exact same question. Inevitably they’ll only allow posts from "members" or the site will be an extract from some mailing list that I'm not on or that stopped existing months or even years ago. Then I go back to work.

The web is a great place for collaboration ... but I can't help but feeling that when it comes to the specific field of developer problems we're collaborating our questions very well but not the solutions.

Hence the Dev-Answers blog is born.

I really wouldn't expect people to read this regularly ... I expect this to be the longest post. My only hope is that if you search for a specific problem and end up being directed here, the specific solution (for me at least) will be here.

Comments are welcome as long as they add to the understanding of the problem/solution described. If you have a question use one of the various other forums to post it and then when you have an answer, post it here.

If no one uses this at all then at least it's an online version of my notebook ...

No Questions!