Thursday, August 25, 2005

more xml schema validation

I thought I had Xml validation sorted after the following entries (java and xml, and schema validation).

So today when I went to validate some xml's against a Xsd I was a bit surprised when it didn't work

What was more surprising was that it was working, and when I changed something small, it stopped.

As part of a Unit Test I was validating an xml file against a schema, and it was working fine. However I was loading the Xsd via a webserver into the parser. This wouldn't do since other developpers would want to run the unit tests and would not want the hassle of starting up a webserver and dropping the xsd file in place initally before running the tests.

So I changed the URL to load the Xsd via the file:// protocal. See below

xsd="file://"+path+"wishlist.xsd";


Running that however gave the following exception



org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'wishList'.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
....


But I knew the XSD was correct because it had been working before when I retrieved it via http:// on my webserver....

Do you see the problem? Well I didn't initially. After some poking around I found the solution.

xsd="file:///"+path+"wishlist.xsd";

See the difference. Subtle isn't it. Basically xerces insists that file needs 3 forward slashes in it url definition (file:///wishlist.xsd). That was the problem. Surely a better error message could have been generated there. (Maybe XSD not found or something)

Anyway I then started gettign the following error



org.xml.sax.SAXParseException: Invalid byte 1 of 1-byte UTF-8 sequence.
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
...


Short answer to this problem was my file character encoding. I had saved my xsd using a free editor (crimson). By default it saves files in Ascii encoding. However my Xsd expected to be in UTF-8. Changing the character encoding and re-saving solved the problem.

Amazing how a simple little task can tie you down for hours..

Monday, August 15, 2005

Regular expressions tutorial

I can never remember Regular Expressions (regex).

So heres a good tutorial on the subject I found. http://www.silverstones.com/thebat/Regex.html

once you've read that, then pick one of the following results as a quick reference card.
http://www.google.ie/search?q=regex+quick+reference


---Added Jul 13 ----
Just found this great site for validating your regex's online.. Brilliant.

http://www.koralsoft.com/regextester/

Regexs
Strip html from strings
//javascript Makes <b>Hello</b> World => Hello World
tag = tag.replace(/(<([^>]+)>)/ig,"");

Split CamelCase word (Note performance might not be great for many iterations)
s.replaceAll("([A-Z])", ' $1'); // taken from here

Slight modification (don't split if more than one capital after another)
s.replaceAll("([A-Z]{1,})", ' $1');

Thursday, August 04, 2005

Remote Debugging Java with eclipse

This is a powerful feature which allows you to debug a remote server from an IDE, and step through the code to see what is happening. For example a remote web server like tomcat, or an app server like WebLogic or Websphere can be debugged.

Firstly the basis of this is a feature in the Java JVM. This means that any java executable can be debugged this way.

To start debugging on a java instance you need to include the following when you run the JVM

java -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=n,suspend=n,address=8000 -Djava.compiler=NONE

For running Weblogic Server in debug mode subtle difference
java -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -Djava.compiler=NONE

This sets the debugger listening on a socket on port 8000.

Debugging can also be set up using shared memory, but eclipse can't use the shared memory feature so I won't deal with it here (BTW, Netbeans can use the shared memory mechanism for debugging so this can be pursued if you are using Netbeans)

Simply then within eclipse you need to select Run/Debug.... From there select Remote Debugging, select the project where you have the source code for the project, and specify the server name where the service is running and the port (8000 in our case), and you're laughing.

Easy peasy.

If you are running tomcat (well version 5.5 anyway), the startup scripts already have the debugging information included, see this link
http://jakarta.apache.org/tomcat/faq/development.html

What I've done then is simply changed the startup.bat file.

At the start (line 9) I added the following, which specifies socket based debugging (shared memory is the default), and sets the listen port to 8000
rem ++++++++++++++++++++++++++++++++++++++
rem Enable Remote Debugging
set JPDA_ADDRESS=8000
set JPDA_TRANSPORT=dt_socket
rem ++++++++++++++++++++++++++++++++++++++

Careful of any extra spaces of tabs on these line. An extra space caused me some problems for a while.

Then change the 2nd last line where it calls the catalina.bat file from
call "%EXECUTABLE%" %CMD_LINE_ARGS% start

to

call "%EXECUTABLE%" start %CMD_LINE_ARGS%

Now when you call the startup.bat you can simply call startup jpda to start the debugger listening on port 8000. Then you can attach your IDE to port 8000 and debug the server.

Alternatively you can simply call the catalina.bat file directly using the command

catalina.bat jpda start

But you must declare JPDA_ADDRESS=8000 and JPDA_TRANSPORT=dt_socket as environment variable (or put them in the catalina.bat)

Weblogic

Remote debugging with eclipse

To enable remote debugging for weblogic the following must be done

In the setDomainEnv.cmd or setDomainEnv.sh you must assign the variable debugFlag to true. (Note no need for quotes etc as I discovered after some time debugging)

setDomnainEnv.cmd

set debugFlag=true

setDomainEnv.sh

local debugFlag=true