If you've worked with ZK for a bit, you will know that it uses an EL style of expression to set values and perform actions anywhere in the page. Which means you should be able to do something like:
<radio label="Sale" onCheck="${priceLabel.value='fruit'}"/>
However, this is not correct, in fact EL expressions will not be evaluated at all for the above line. The correct way to do it is as follows:
<radio label="Sale" onCheck="priceLabel.value="fruit""/>
Why? The developers guide explains it: "you could use EL expressions in any part of ZUML pages, except the names of attributes,
elements and processing instructions"
As the above is a processing instruction, you need to drop the EL syntax, which is a little strange as the syntax remains the same and is apparently still processed by BeanShell. Oh well. As for the escaping, that's just well-formed XML.
Friday, July 27, 2007
Sunday, July 22, 2007
Transaction management with Spring / Hibernate + ZK
Normal Spring transaction management for Hibernate does not work out of the box with ZK. Actually to be exact the transaction management works fine, but the Hibernate session is not kept open after the transaction until the end of the request as it should when using OpenSessionInViewFilter. The end result is that you get LazyInitializationException when trying to access proxies, since the session is closed.
To fix this, a file called WEB-INF/zk.xml must be created with the following contents:
The problem is that the Spring OpenSessionInViewFilter opens a session, and binds it to the request's thread. However, ZK uses a multi-threaded event driven approach, so the actual processing happens in a new thread that gets kicked off by the ZK servlet - this breaks the connection to the open session. Adding the above listener copies the ThreadLocal variables with the session etc from the request thread's context into the event thread. As you can see, more prefs can be added to copy other objects from the ThreadLocal context.
I had to inspect a lot of code to fix this, turns out it was documented in great detail all along (but sort of all over the place):
Another possible solution is to make the ZK servlet perform all processing within its own thread, this was a new feature in ZK 2.4. I haven't tried this though and it looks like this may be dangerous, since the thread will block the entire servlet if it blocks for any reason. To enable this, the following is required in the zk.xml:
To fix this, a file called WEB-INF/zk.xml must be created with the following contents:
<zk><</zk>listener>
<
description>ThreadLocal Variables Synchronizer
</description>
<
listener-class>org.zkoss.zkplus.util.ThreadLocalListener
</listener-class>
</listener>
<preference>
<
name>ThreadLocal
</name>
<
value>
org.springframework.transaction.support.TransactionSynchronizationManager=resources,synchronizations,currentTransactionName,currentTransactionReadOnly,actualTransactionActive;
org.springframework.orm.hibernate3.SessionFactoryUtils=deferredCloseHolder;
org.springframework.transaction.interceptor.TransactionAspectSupport=transactionInfoHolder;<
/value>
</preference>
The problem is that the Spring OpenSessionInViewFilter opens a session, and binds it to the request's thread. However, ZK uses a multi-threaded event driven approach, so the actual processing happens in a new thread that gets kicked off by the ZK servlet - this breaks the connection to the open session. Adding the above listener copies the ThreadLocal variables with the session etc from the request thread's context into the event thread. As you can see, more prefs can be added to copy other objects from the ThreadLocal context.
I had to inspect a lot of code to fix this, turns out it was documented in great detail all along (but sort of all over the place):
- The 'old' way of fixing the issue, and only sufficient if you use Hibernate without Spring transactions: http://zkoss.org/javadoc/2.4.1/zkplus/org/zkoss/zkplus/hibernate/HibernateSessionContextListener.html
- The 'new' way of fixing it, but the example only shows how to emulate the above, so again not sufficient for Spring transactions: http://www.zkoss.org/smalltalks/zk2.4.1/zk2.4.1.dsp
- The javadoc with the 'new' way, surprisingly enough with exactly the example prefs I was looking for: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ThreadLocal.html
Another possible solution is to make the ZK servlet perform all processing within its own thread, this was a new feature in ZK 2.4. I haven't tried this though and it looks like this may be dangerous, since the thread will block the entire servlet if it blocks for any reason. To enable this, the following is required in the zk.xml:
<system-config>
<
disable-event-thread/>
<
/system-config>
Friday, July 20, 2007
Getting Maven to do ZK
I couldn't find the Maven dependecies for ZK on the zkoss site, so here is what I had to include in my pom.xml to get it working. Beanshell is pretty central to ZK so I'm not sure why it doesn't get pulled in with the base ZK dependency. The jhlabs dependency is needed for captchas, if you're going to need that. By the way I would post the actual XML except then I have to escape the tags which is painful.
org.zkoss.zk:zkplus:2.4.1
org.zkoss.common:zweb:2.4.1
org.zkoss.common:zcommon:2.4.1
org.zkoss.zkforge:fckez:2.3-3
org.zkoss.zk:zul:2.4.1
org.zkoss.zk:zhtml:2.4.1
org.zkoss.zkforge:timelinez:1.1_3
org.zkoss.zk:zk:2.4.1
com.jhlabs:filters:2.0.235
org.beanshell:bsh:2.0b4
org.zkoss.zk:zkplus:2.4.1
org.zkoss.common:zweb:2.4.1
org.zkoss.common:zcommon:2.4.1
org.zkoss.zkforge:fckez:2.3-3
org.zkoss.zk:zul:2.4.1
org.zkoss.zk:zhtml:2.4.1
org.zkoss.zkforge:timelinez:1.1_3
org.zkoss.zk:zk:2.4.1
com.jhlabs:filters:2.0.235
org.beanshell:bsh:2.0b4
ZK + Eclipse: XML schema validation / Content assist
To get Eclipse to use content assist with ZK, I had to declare the schema as follows. This took me a while to figure out for some reason. I use MyEclipse, by the way, so WTP should be similiar.
<window xmlns="http://www.zkoss.org/2005/zul" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd">
</window>
<window xmlns="http://www.zkoss.org/2005/zul" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd">
</window>
Subscribe to:
Posts (Atom)