Saturday May 17, 2008
AppFuse + DisplayTag: External Sorting and Paging Example Chris Barham has posted an excellent example of how to do external sorting and paging to the AppFuse mailing list:
I've put together a new AppFuse project which demonstrates how to enhance the List screens. DisplayTag as provided has issues with large datasets, (it retrieves all the records every time), and sorting via column headings does not work for the entire dataset, only those on screen at the time.
I've built a project which addresses these issues, using Hibernate Criteria and extensions to DisplayTags PaginatedList interface which gets DisplayTag to hand off all requests for sorting and paging to the new implementation of PaginatedList.
The Google Code project is checked in to: http://code.google.com/p/pagingappfuse/ feel free to check out the code and comment. (instructions here: http://code.google.com/p/pagingappfuse/source/checkout)
There are instructions regarding the steps taken on the project wiki page here: http://code.google.com/p/pagingappfuse/wiki/PagingSorting
Cheers,
Chris
Nice work - thanks Chris! Posted in Java at May 17 2008, 08:19:55 AM MDT 1 Comment
Spring MVC vs. JSF and The State of Spring Web Alternative Adult has only posted a couple times in 2008, but his entries have peaked my interest.
Spring MVC or JSF+?
My business unit is trying to standardize if we can on a single Java-based Web framework going forward to simplify the Web development process, especially as individual developers move from one division to another, or centralized support groups need to maintain multiple applications from multiple divisions.
At the enterprise level within my company, the architecture group says that they will provide support for either Spring MVC or JSF+ (where the + represents the accompanying technologies you would use to provide a more maintainable application and a more rich user experience, e.g. Facelets, Richfaces, etc.).
Now my business unit is trying to decide which of these two frameworks, Spring MVC or JSF+, is the most appropriate to standardize upon for our development community. [Read More]
...and...
State of Spring Web
For those that are interested, the following is a summary of the notes I captured from a conversation with SpringSource on the state of Spring Web. [Read More]
Good stuff Michael - keep it coming. Posted in Java at May 16 2008, 06:17:52 PM MDT 1 Comment
Extensionless URLs with Java Web Frameworks Last week, I had a go of making a Spring MVC application use extensionless URLs. I did some googling, found some tips on the Spring Forums and believe I arrived at a solid solution. Using the UrlRewriteFilter (version 3), I was able to create a rule that looks for any URLs without an extension. If it finds one, it appends the extension and forwards to the controllers. This rule is as follows (where *.html is my servlet-mapping for DispatcherServlet in web.xml):
<rule>
<from>^([^?]*)/([^?/\.]+)(\?.*)?$</from>
<to last="true">$1/$2.html$3</to>
</rule>
As long as I hand-write all my URLs without an extension (<a href="home"> vs. <a href="home.html">), this seems to work. To combat developers that use "home.html", one solution is to require all links to be wrapped with <c:url value="url"/> (or some other macro that call response.encodeURL()). If you can convince everyone to do this, you can write an outbound-rule that strips the .html extension from URLs.
<outbound-rule>
<from>^(.*)\.html(\?.*)?$</from>
<to last="false">$1$2</to>
</outbound-rule>
In an ideal world, it'd be possible to modify the <a> tag at the very core of the view framework you're using to automatically encode the URL of any "href" attributes. I don't think this is possible with JSP, FreeMarker, Facelets or any other Java Web Framework templates (i.e. Tapestry or Wicket). If it is, please let me know.
Below is my final urlrewrite.xml with these rules, as well as my "welcome-file" rule at the top.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN"
"http://tuckey.org/res/dtds/urlrewrite3.0.dtd">
<urlrewrite>
<rule>
<from>/$</from>
<to type="forward">home</to>
</rule>
<rule>
<from>^([^?]*)/([^?/\.]+)(\?.*)?$</from>
<to last="true">$1/$2.html$3</to>
</rule>
<outbound-rule>
<from>^(.*)\.html(\?.*)?$</from>
<to last="false">$1$2</to>
</outbound-rule>
</urlrewrite>
If you have other solutions for extensionless URLs with Java web frameworks, I'd love to hear about them. With any luck, 2008 will be the year we drop extensions (and path-mappings) from our URLs. The stat packages might not like it, but I do. Posted in Java at May 13 2008, 09:50:51 PM MDT 14 Comments
AppFuse 2.0.2 Released The AppFuse Team is pleased to announce the release of AppFuse 2.0.2. This release includes upgrades to Spring Security 2.0, jMock 2.4, the ability to customize code generation templates and many bug fixes.
For information on upgrading from 2.0.1, see the Release Notes or changelog. AppFuse 2.0.2 is available as a Maven archetype. For information on creating a new project using AppFuse, please see the QuickStart Guide or the demos and videos.
To learn more about AppFuse, please read Ryan Withers' Igniting your applications with AppFuse.
The 2.0 series of AppFuse has a minimum requirement of the following specification versions:
- Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)
- Java 5+
If you've used AppFuse 1.x, but not 2.x, you'll want to read the FAQ. Join the user mailing list if you have any questions.
Thanks to everyone for their help contributing code, writing documentation, posting to the mailing lists, and logging issues.
Please post any issues you have with this release to the mailing list.
Posted in Java at May 11 2008, 11:25:40 PM MDT 3 Comments
AppFuse Light 1.8.2 Released AppFuse Light 1.8.2 is a bug fixes release that includes upgrades for Spring, Spring Security, Hibernate, Wicket, Tapestry and many others. In addition, Spring bean definitions were replaced with annotations (@Repository, @Service and @Controller). See the Release Notes for more information on what's changed since the last release.
AppFuse Light now offers 60 possible combinations for download:
- Web Frameworks: JSF (MyFaces), Spring MVC (with Ajax, Acegi Security, JSP, FreeMarker or Velocity), Stripes, Struts 1.x, Struts 2.x, Tapestry, WebWork, Wicket
- Persistence Frameworks: Hibernate, iBATIS, JDO (JPOX), OJB, Spring JDBC
If you have any questions about this release, please subscribe to the AppFuse user mailing list by sending a blank e-mail to users-subscribe@appfuse.dev.java.net. You can also post questions in a forum-like fashion using Nabble: http://appfuse.org/forum/user. Posted in Java at May 11 2008, 10:16:17 PM MDT Add a Comment
Issues with AntRun Plugin and Maven I started seeing the following error today when using Maven and the AntRun Plugin.
[INFO] [antrun:run {execution: default}]
[INFO] Executing tasks
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error executing ant tasks
Embedded error: java.lang.IllegalAccessError: tried to access method
org.apache.tools.ant.launch.Locator.decodeUri(Ljava/lang/String;)Ljava/lang/String;
from class org.apache.tools.ant.AntClassLoader
Searching the internet provided no results, so I was pretty stumped - especially since this error didn't happen on my MacBook Pro. It happened on AppFuse's Bamboo server (Linux), but not locally. Luckily, I was able to reproduce it on my Windows box and discovered the solution: upgrade to a newer version of Maven. I was using 2.0.6/2.0.7 and upgrading to 2.0.9 fixed the problem.
BTW, when is the Ant project going to release a new version of Ant? The current 1.7.0 version doesn't support spaces in path names, which seems like a pretty big issue to me (especially for Windows users). Posted in Java at May 10 2008, 06:23:26 PM MDT 3 Comments
JavaOne Parties Update In an effort to keep one of the top spots for "javaone parties", here's the updated list for JavaOne parties this week:
- Tuesday: CodeGear: Thirsty Bear @ 5:30, Open Source UnBOF: Thirsty Bear @ 8, TangoSolarMetric: Zebulon @ 9
- Wednesday: Adobe: Jillian's @ 6:30, Eclipse: Thirsty Bear @ 7, Tiki Bar Party: The Bamboo Hut @ 8
- Thursday: JBoss: Jillian's @ 5:30, QCon: Zebulon @ 6:30
Thanks to Atlassian for the free beer last night at Thirsty Bear. I'll likely be at Thirsty Bear tonight, followed by Zebulon. Let the networking begin!
Related: JavaOne: Where are the good parties at? Posted in Java at May 06 2008, 12:20:28 PM MDT 1 Comment
Running Spring MVC Web Applications in OSGi For the past couple of weeks, I've been developing a web application that deploys into an OSGi container (Equinox) and uses Spring DM's Spring MVC support. The first thing I discovered was that Spring MVC's annotations weren't supported in the M1 release. This was apparently caused by a bug in Spring 2.5.3 and not Spring DM. Since Spring DM 1.1.0 M2 was released with Spring 2.5.4 today, I believe this is fixed now.
The story below is about my experience getting a Spring MVC application up and running in Equinox 3.2.2, Jetty 6.1.9 and Spring DM 1.1.0 M2 SNAPSHOT (from last week). If you want to read more about why Spring MVC + OSGi is cool, see Costin Leau's Web Applications and OSGi article.
To get a simple "Hello World" Spring MVC application working in OSGi is pretty easy. The hard part is setting up a container with all the Spring and Jetty bundles installed and started. I imagine SSAP might solve this. Luckily for me, this was done by another member of my team.
After you've done this, it's simply a matter of creating a MANIFEST.MF for your WAR that contains the proper information for OSGi to recognize. Below is the one that I used when I first tried to get my application working.
Manifest-Version: 1 Bundle-ManifestVersion: 2 Spring-DM-Version: 1.1.0-m2-SNAPSHOT Spring-Version: 2.5.2 Bundle-Name: Simple OSGi War Bundle-SymbolicName: myapp Bundle-Classpath: .,WEB-INF/classes,WEB-INF/lib/freemarker-2.3.12.jar, WEB-INF/lib/sitemesh-2.3.jar,WEB-INF/lib/urlrewritefilter-3.0.4.jar, WEB-INF/lib/spring-beans-2.5.2.jar,WEB-INF/lib/spring-context-2.5.2.jar, WEB-INF/lib/spring-context-support-2.5.2.jar,WEB-INF/lib/spring-core-2.5.2.jar, WEB-INF/lib/spring-web-2.5.2.jar,WEB-INF/lib/spring-webmvc-2.5.2.jar Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree, javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional, org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional
Ideally, you could generate this MANIFEST.MF using the maven-bundle-plugin. However, it doesn't support WARs in its 1.4.0 release.
You can see this is an application that uses Spring MVC, FreeMarker, SiteMesh and the URLRewriteFilter. You should be able to download it, unzip it, run "mvn package" and install it into Equinox using "install file://<path to war>".
That's all fine and dandy, but doesn't give you any benefits of OSGi. This setup works great until you try to import OSGi services using a context file with an <osgi:reference> element. After adding such a reference, it's likely you'll get the following error:
SEVERE: Context initialization failed org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/osgi]
To fix this, add the following to your web.xml (if you're using ContextLoaderListener, as an <init-parameter> on DispatcherServlet if you're not):
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
</context-param>
After doing this, you might get the following error on startup:
SEVERE: Context initialization failed org.springframework.context.ApplicationContextException: Custom context class [org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext] is not of type [org.springframework.web.context.ConfigurableWebApplicationContext]
To fix this, I change from referencing the Spring JARs in WEB-INF/lib to importing the packages for Spring (which were already installed in my Equinox container).
Bundle-Classpath: .,WEB-INF/classes,WEB-INF/lib/freemarker-2.3.12.jar, WEB-INF/lib/sitemesh-2.3.jar,WEB-INF/lib/urlrewritefilter-3.0.4.jar Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree, javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional, org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional, org.springframework.osgi.web.context.support, org.springframework.context.support, org.springframework.web.context, org.springframework.web.context.support, org.springframework.web.servlet, org.springframework.web.servlet.mvc, org.springframework.web.servlet.mvc.support, org.springframework.web.servlet.view, org.springframework.ui, org.springframework.web.servlet.view.freemarker
After rebuilding my WAR and reloading the bundle in Equinox, I was confronted with the following error message:
SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'freemarkerConfig' defined in ServletContext
resource [/WEB-INF/myapp-servlet.xml]: Instantiation of bean failed;
nested exception is java.lang.NoClassDefFoundError:
freemarker/cache/TemplateLoader
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:851)
As far as I can tell, this is because the version of Spring MVC installed in Equinox cannot resolve the FreeMarker JAR in my WEB-INF/lib directory.
To prove I wasn't going insane, I commented out my "freemarkerConfig" and "viewResolver" beans in myapp-servlet.xml and changed to a regular ol' InternalResourceViewResolver:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
This worked and I was able to successfully see "Hello World" from a JSP in my browser. FreeMarker/SiteMesh worked too, but FreeMarker didn't work as a View for Spring MVC.
To attempt to solve this, I create a bundle for FreeMarker using "java -jar bnd-0.0.249.jar wrap freemarker-2.3.12.jar" and installed it in Equinox. I then change my MANIFEST.MF to use FreeMarker imports instead of referencing the JAR in WEB-INF/lib.
Bundle-Classpath: .,WEB-INF/classes,WEB-INF/lib/sitemesh-2.3.jar,WEB-INF/lib/urlrewritefilter-3.0.4.jar Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree, javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional, org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional, org.springframework.osgi.web.context.support, org.springframework.context.support, org.springframework.web.context, org.springframework.web.context.support, org.springframework.web.servlet, org.springframework.web.servlet.mvc, org.springframework.web.servlet.mvc.support, org.springframework.web.servlet.view, org.springframework.ui, org.springframework.web.servlet.view.freemarker, freemarker.cache,freemarker.core,freemarker.template,freemarker.ext.servlet
Unfortunately, this still doesn't work and I still haven't been able to get FreeMarker to work with Spring MVC in OSGi. The crazy thing is I actually solved this at one point a week ago. Shortly after, I rebuilt Equinox from scratch and I'm been banging my head against the wall over this issue ever since. Last week, I entered an issue in Spring's JIRA, but thought I'd fixed it a few hours later.
I've uploaded the final project that's not working to the following URL:
http://static.raibledesigns.com/downloads/myapp-osgi.zip
If you'd like to see this project work with Spring MVC + JSP, simply modify myapp-servlet.xml to remove the FreeMarker references and use the InternalResourceViewResolver instead.
I hope Spring DM + Spring MVC supports more than just JSP as a view technology. I hope I can't get FreeMarker working because of some oversight on my part. If you have a Spring DM + Spring MVC application working with Velocity or FreeMarker, I'd love to hear about it. Posted in Java at Apr 30 2008, 12:42:34 AM MDT 9 Comments
JavaOne: Where are the good parties at? In a week from today, I'll begin the annual trek to one of the best conferences on the planet: JavaOne. By "best conferences", I don't mean it has the best technical content - that award goes to NFJS, The Colorado Software Summit and The Spring Experience.
JavaOne has the best networking opportunities. Of all the conference-goers I know, most of them will be at JavaOne.
I'm flying into San Francisco on Monday, driving to Mountain View to work for a few hours, playing in the company's weekly softball game, then heading back to downtown San Francisco for the networking. Tuesday through Thursday, I plan on doing the same thing: commuting to Mountain View during the day, returning to JavaOne for the parties. I have a free blogger pass, so I could attend sessions, but networking seems more important. If there's any good BOFs at night, I may attend those.
So where and where are the good parties at JavaOne 2008? Here's what I know about so far - I'll add to this list as comments start flowing in:
- Sunday: GlassFish: Thirsty Bear @ 7
- Monday: IONA: Zebulon @ 6, JavaBloggers: Thirsty Bear @ 7:30
- Tuesday: CodeGear: Thirsty Bear @ 5:30, TangoSolarMetric: Zebulon @ 9
- Wednesday: Adobe: Jillian's @ 6:30, Eclipse: Thirsty Bear @ 7, Tiki Bar Party: The Bamboo Hut @ 8
- Thursday: JBoss: Jillian's @ 5:30, QCon: Zebulon @ 6:30
I don't have details on the JBoss party, but I did receive an e-mail about it. Since my flight leaves before the party starts, I must've deleted it.
When and where is the Java Bloggers Meetup? What about the Solarmetric/Tangosol party? Is it now the SpringSource/BEA/Oracle party?
See y'all next week - I hope the networking opportunities are better than ever.
Related: JavaOne 2004, JavaOne 2005 and JavaOne 2006. Posted in Java at Apr 28 2008, 08:21:34 AM MDT 6 Comments
Upgrading to Spring Security 2.0 This evening I spent a few hours and upgraded AppFuse to use Acegi Spring Security 2.0. The upgrade was fairly straightforward:
- %s/org.acegisecurity/org.springframework.security/g
- Upgraded dependencies (exclusions are necessary if you're using Spring 2.5.x and don't want 2.0.x dependencies pulled in):
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core-tiger</artifactId> <version>${spring.security.version}</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-support</artifactId> </exclusion> </exclusions> </dependency> ... <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>${spring.security.version}</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </exclusion> </exclusions> </dependency> - Changed taglib prefix from "authz" to "security" and change the associated taglib declaration to:
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="security" %> - In web.xml, I changed <filter-class> to org.springframework.web.filter.DelegatingFilterProxy. Since I didn't name my filter springSecurityFilterChain, I also had to add the following <init-param>:
<init-param> <param-name>targetBeanName</param-name> <param-value>springSecurityFilterChain</param-value> </init-param> - Lastly, I modified security.xml to use the new syntax. AppFuse's security.xml went from 175 lines to 33 with the new security namespace configuration!
It's hard to believe I first looked at Acegi almost 4 years ago. At that time, I said it contained too much XML for my needs. Ben's reaction:
Seriously, the "whole lotta XML" gives you exponentially more power and flexibility than a method such as this could ever hope to provide you.
It's nice to see that Spring Security 2.0 gives you exponentially more power and flexibility without all the XML. Thanks guys!
P.S. You can also view the full changelog for this upgrade.
Update: If you're using <authz:authentication property="fullName"/> in your JSPs, you'll need to change it to <security:authentication property="principal.fullName"/>. Posted in Java at Apr 17 2008, 02:45:47 AM MDT 12 Comments
Search This Site
Recent Entries
- AppFuse + DisplayTag: External Sorting and Paging Example
- Spring MVC vs. JSF and The State of Spring Web
- Extensionless URLs with Java Web Frameworks
- AppFuse 2.0.2 Released
- AppFuse Light 1.8.2 Released
- Issues with AntRun Plugin and Maven
- JavaOne Parties Update
- Happy Cinco de Linko!
- Denver Weather
- Running Spring MVC Web Applications in OSGi
