Thursday, July 9, 2009

Python's Lazy Evaluation on Exception Handling

I tried a simple code like this:

[sourcecode lang="python"]
try:
while True:
print('yipee')
except KeyboardInterrupt:
print('w00t')
[/sourcecode]

It runs successfully on command line interface, and keeps printing "yipee" until the user press Ctrl-C. After that I did a typo, which turns out to mistype the "KeyboardInterrupt" as "KeybaordInterrupt".

[sourcecode lang="python"]
try:
while True:
print('yipee')
except KeybaordInterrupt:
print('w00t')
[/sourcecode]

To my surprise, it still runs well, it keeps printing "yipee" to the screen. It's just that
when I press Ctrl-C, Python threw this error:

[sourcecode lang="shell"]
Traceback (most recent call last):
File '<stdin>', line 3, in <module>
KeyboardInterrupt
[/sourcecode]

During handling of the above exception, another exception occurred:

[sourcecode lang="shell"]
Traceback (most recent call last):
File '<stdin>', line 4, in <module>
NameError: name 'KeybaordInterrupt' is not defined
[/sourcecode]

I looked at the documentation of Python 3.1 which says:
The try statement works as follows.

First, the try clause (the statement(s) between the try and except keywords) is executed.

  • If no exception occurs, the except clause is skipped and execution of the try statement is finished.

  • If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then if its type matches the exception named after the except keyword, the except clause is executed, and then execution continues after the try statement.

  • If an exception occurs which does not match the exception named in the except clause, it is passed on to outer try statements; if no handler is found, it is an unhandled exception and execution stops with a message as shown above.


The exception handling in Python works in a lazy manner, they will only validate the except clauses just before processing the exception!

Wednesday, July 1, 2009

Adding Embedded ActiveMQ to Spring Container (on Maven 2 Project)

Today, we need to add a queue to our application to better manage long running transaction on our web application. The choice fell into using embedded ActiveMQ.We plan to use the latest version available (which currently ActiveMQ 5.2.0). Previous version of our application use our proprietary code which I believe was an example of reinventing the wheel. For our latest version of application, we try to use as much as possible open standard and open source technologies. ActiveMQ is under the Apache Software Foundation umbrella which is suitable for us.

First I add the dependency for the latest version of ActiveMQ (version 5.2.0):

[sourcecode lang="xml"]
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.2.0</version>
<optional>false</optional>
</dependency>
[/sourcecode]

Now it's time to add something into the Spring application context configuration file.
As suggested by the documentation, I added new namespace amq in my XML. It points to "http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd" schema location.

[sourcecode lang="xml"]
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:amq="http://activemq.apache.org/schema/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
[/sourcecode]

I tried to run a JUnit test just to make sure that the new change in the configuration works well. There were some 2 errors. It turns to be a stale schema location. I figured it out from opening the URL http://activemq.apache.org/schema/core and see what's in there. So now need to modify a bit, change "http://activemq.apache.org/schema/core/activemq-core.xsd" to "http://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd".

So here goes the correct version that works (syntactically correct XML):

[sourcecode lang="xml"]
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:amq="http://activemq.apache.org/schema/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd">
[/sourcecode]

Now the next beast coming in, when I tried to use the new namespace by adding this inside the <beans/> tag.

[sourcecode lang="xml"]
<amq:broker useJmx="false" persistent="false">
<amq:transportConnectors>
<amq:transportConnector uri="tcp://localhost:0" />
</amq:transportConnectors>
</amq:broker>
[/sourcecode]

It produced this error:

[sourcecode lang="shell"]

java.lang.ExceptionInInitializerError
at com.triquesta.tcm.core.services.MessagingServiceTest.init(MessagingServiceTest.java:17)
[...deleted...]
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [tcm_configs.xml]; nested exception is org.springframework.beans.FatalBeanException: NamespaceHandler class [org.apache.xbean.spring.context.v2.XBeanNamespaceHandler] for namespace [http://activemq.apache.org/schema/core] not found; nested exception is java.lang.ClassNotFoundException: org.apache.xbean.spring.context.v2.XBeanNamespaceHandler
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:420)
[...deleted...]
Caused by: org.springframework.beans.FatalBeanException: NamespaceHandler class [org.apache.xbean.spring.context.v2.XBeanNamespaceHandler] for namespace [http://activemq.apache.org/schema/core] not found; nested exception is java.lang.ClassNotFoundException: org.apache.xbean.spring.context.v2.XBeanNamespaceHandler
at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(DefaultNamespaceHandlerResolver.java:134)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1292)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1287)
[...deleted...]
Caused by: java.lang.ClassNotFoundException: org.apache.xbean.spring.context.v2.XBeanNamespaceHandler
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at org.springframework.util.ClassUtils.forName(ClassUtils.java:211)
at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(DefaultNamespaceHandlerResolver.java:123)
... 37 more
[/sourcecode]