Matt RaibleMatt Raible is a Web Developer and Java Champion. Connect with him on LinkedIn.

The Angular Mini-Book The Angular Mini-Book is a guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.

Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with Spring Boot and use security best practices like HTTPS and a content security policy.

For book updates, follow @angular_book on Twitter.

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.
You searched this site for "appfuse". 771 entries found.

You can also try this same search on Google.

Moving from Spring's XML to Annotations in AppFuse

Last night, I did a spike on AppFuse to change XML to Spring annotations (@Repository, @Service and @Autowired) in its service and data modules. While I was able to accomplish everything in a few hours (including converting tests), I did run into a couple issues.

AbstractTransactionalJUnit4..Tests vs. AbstractTransactionalDataSource..Tests
I've switched from my favorite Spring class to the annotation-happy AbstractTransactionalJUnit4SpringContextTests. However, this has presented an issue: when using ATDSSCT, I was able to call endTransaction() and startNewTransaction(). With ATJ4SCT, this doesn't seem possible. Below is a screenshot of the diff on a test method in the JPA implementation of UserDaoTest:

AbstractTransactionalJUnit4SpringContextTests vs. AbstractTransactionalDataSourceSpringContextTests

On the right, you'll notice that I had to comment out @ExpectedException to get the test to pass. This concerns me since this exception should be thrown. Is there a way to call endTransaction() and startNewTransaction() when subclassing AbstractTransactionalJUnit4SpringContextTests?

Instantiating GenericDao Implementations Programmatically
The second feature I tried to add is the ability to instantiate a GenericDao programatically rather than requiring a XML bean definition. In current versions of AppFuse, you can use the following bean definition to create a GenericDao for a model object.

<bean id="personDao" class="org.appfuse.dao.hibernate.GenericDaoHibernate">
    <constructor-arg value="org.appfuse.tutorial.model.Person"/> 
    <property name="sessionFactory" ref="sessionFactory"/>
</bean> 

When moving to a no-XML required architecture, it'd be nice to allow users to create GenericDao's programmatically. Below is the easiest way I've found to do this in a test:

GenericDao<User, Long> genericDao;
@Autowired
SessionFactory sessionFactory;

@Before
public void setUp() {
    genericDao = new GenericDaoHibernate<User, Long>(User.class);
    genericDao.setSessionFactory(sessionFactory);
}

However, there's a couple problems with this. First of all, mixing constructor injection and setter injection probably isn't a good idea. Changing the constructor to take a SessionFactory solves this problem, but now all subclasses need to have a more verbose constructor:

@Autowired
public UserDaoHibernate(SessionFactory sessionFactory) {
    super(User.class, sessionFactory);
}

Whereas before they had:

public UserDaoHibernate() {
    super(User.class);
}

In an ideal world, I could call new GenericDaoHibernate<User, Long>(User.class) and the SessionFactory would be wired in auto-magically. Is this possible with Spring 2.5?

The 2nd problem this presents is your client code will now be dependent on an implementation rather than the interface. I don't know how to solve that one, but I'd love to figure out a way to create GenericDaos with no XML and no implementation details in the client. Any ideas are most welcome.

If you'd like to see all the changes I made in converting from XML to Annotations, please see this patch.

Posted in Java at Nov 04 2008, 11:39:54 AM MST 14 Comments

Free Maven Training in New Orleans on Election Day

Last week, I attended a talk by Jason van Zyl on Comprehensive Project Intelligence. This talk contained a good overview of some Maven goodies that Jason's company has been working on - namely better repository management (Nexus), better Eclipse support (m2eclipse) and improving an awesome CI server (we use Hudson heavily at LinkedIn).

Colorful New Orleans
Photo by Toshio

It looks like Jason is going to be doing a similar session in a full-day format at ApacheCon next week. The good news is it's free, the bad news is you have to be in New Orleans. Hopefully Jason and team will post their slides from this event and we can all learn how to use Maven more effectively.

In other Maven-related news, I hope to complete AppFuse 2.1 around the same time as Spring 3.0 (early next year). As part of that release, I hope to start using Nexus for AppFuse's repository as well as restructure its archetypes to allow using m2eclipse (with WTP) more effectively.

Posted in Java at Oct 29 2008, 09:55:45 PM MDT Add a Comment

AppFuse Light » AppFuse, Maven Archetypes and Shared Web Assets

Last night, I stayed up into the wee hours of the morning working on something I've been wanting to do for a long time. It wasn't until I was trouncing around the woods in Montana that I realized how easy it would be. The something I've wanted to do was to modify AppFuse Light to use AppFuse's core modules (service and dao). It only took me a few hours to make it happen and it inspired additional ideas.

I believe the major mistake we made in AppFuse 2.x was making it easy for user's to upgrade their applications. We currently use the maven-war-plugin and our own maven-warpath-plugin to make it possible to include AppFuse classes and assets in your project. You can easily start a new project w/o having a whole bunch of files in your project. The problem is, you can't easily use "mvn jetty:run" to work on your project. Of course, you can use "mvn appfuse:full-source" to solve this, but I'm starting to think more and more that "full-source" should be the default. This is what we did in 1.x and it seems to be the more natural pattern for folks using AppFuse.

That hard part about moving to "full-source" by default is coming up with a way to share common assets and classes among wars and war projects. Sure, I can copy all the shared images, css and js into each project - but that could become a maintenance nightmare. Subversion 1.5 with relative svn:externals might solve this, but it still seems kinda hacky. I don't want to use the maven-war-plugin because the overlay is kinda hokey and I think it's easier for users to understand when everything is in their project. AppFuse's current directory structure in SVN looks as follows. I've added indicators of what is in each directory.

AppFuse Web SVN

Rather than using AppFuse's current (manual) archetype-creation process, I'd like to move to a more automated creation process using the maven-archetype-plugin's create-from-project feature. I'd like to figure out a way where I can have the source code and assets from web/common included in each of the other web/* projects (both when using "jetty:run" and "archetype:create-from-project"). One idea I thought of is to make Jetty/Maven aware of multiple src/war directories for "jetty:run" and "package" and then somehow hook into the archetype plugin at creation time to pull in the shared resources. I don't know if something like this is possible. If you know of a good solution to this shared web assets issue, I'd love to hear about it.

Back to AppFuse Light. If I can figure out how to solve shared resources in web modules, I can use this in AppFuse Light to move to a modular SVN structure vs. its current "use Ant to create different combinations" setup. If a modular structure (like appfuse/web/*) is possible for AppFuse Light, I believe it makes sense to move its source into AppFuse's SVN repository. Below is how the directory structure might look after this move.

AppFuse Light » AppFuse

With this addition and "archetype:create-from-project", we should be able to create all the basic and light archetypes automatically. We'll probably still need a manual archetype-creation process for modular archetypes, but I'm OK with that.

The last thing I'm struggling with is figuring out the best way to create archetypes for something like AppFuse. In the past, we've used dependencies to allow users to inherit dependencies and their versions. This works, but it results in a lot of duplicate XML (in projects and archetypes) for developers. Last night, I tried using a parent project instead of dependencies and it seems to work much better. Not only do you inherit dependencies, but you also inherit plugins, profiles and properties. If you inherit, you can override, which is slick.

If you're an AppFuse user, how would you feel about having an AppFuse module as your project's parent? Would you prefer that, dependencies on AppFuse or full-source with no dependencies on AppFuse? Regardless of parent vs. dependencies, I think running "appfuse:full-source" should allow you to de-couple your project from AppFuse.

Posted in Java at Oct 29 2008, 02:18:59 AM MDT 7 Comments

What's Coming in Spring 3.0

This morning, I delivered my What's Coming in Spring 3.0 talk for the 2nd time at Colorado Software Summit. Since there is no Spring 3.0 source code to speak of, I was unable to do the "Choose Your Own Adventure" demo at the end. :(

The good news is I was able to easily upgrade the Spring Kickstart application from Spring 2.0 to Spring 2.5.5 (using annotations). When 3.0 is released, I hope to update this project to use 3.0 as well as show what I needed to change. If I get ambitious, I might even change the UI to use Flex or Ext JS to show a RESTful client. Below is my presentation - hope you enjoy.

Posted in Java at Oct 22 2008, 11:51:12 AM MDT 12 Comments

Ajaxified Body

I've often wondered if it was possible to use Ajax to reload the main content of a web application without reloading the header, menu and footer. SiteMesh allows you to move these common elements to a decorator that gets wrapped around each page. Below is a diagram of how SiteMesh works.

SiteMesh

You can read the Introduction to SiteMesh article if you're interested in learning more about SiteMesh's basic features. By default, SiteMesh decorates text/html responses and ignores any other content type (e.g. image/gif). It also contains an <excludes> configuration element that allows you to turn off decoration when a URL matches a certain pattern. For example, the following allows you to disable decoration when "ajax=true" is passed in the URL.

<excludes>
    <pattern>**ajax=true</pattern>
</excludes>

To optimize the loading of an application so the common elements aren't loaded for each page, it should be possible to create an Ajaxified Body where the primary content area (PCA) of the site is loaded via Ajax rather than refreshing the whole page. The header, footer and navigation bar often stays the same from page-to-page, so it doesn't seem to make a whole lot of sense to load them each time the page loads. The image below shows the PCA (of an AppFuse Light application) as a grey square with a red border.

Ajaxified Body - AppFuse Light

Implementing an Ajaxified Body consists of the following steps:

  1. Adding SiteMesh and moving common elements to a decorator.
  2. Remove common elements from each individual page (if you're using includes).
  3. Configure SiteMesh so decoration is disabled when the requested URL contains "ajax=true".
  4. Write JavaScript that modifies all <a href=""> links (and buttons with onclick='location.href') in the PCA to have an onclick handler.
  5. The onclick handler should call a JavaScript function that loads the link's URL + ajax=true using XMLHttpRequest (XHR).
  6. Add XHR success handling to replace the PCA with the loaded content.
  7. Add XHR error handling to go to the URL normally when response.status != 200.
  8. Inspect the response HTML for <title> element and replace document.title if exists.
  9. Inspect the response HTML for <head> element and append to current if exists.
  10. Inspect the response HTML for <script> and <link> elements (JavaScript and CSS) and evaluate them if they exist.

As a proof of concept, I created a prototype using AppFuse Light (Prototype/Scriptaculous for Ajax). You can see a demo at the following URL. You can also download a patch or the source for this project.

http://demo.raibledesigns.com/ajaxifiedbody

Below are a number of things I discovered while writing this prototype:

  • The hardest part of implementing this seems to be coding the exceptions. It's possible you'll have some links with existing onclick handlers and you may have to disable "ajaxifying links" for those links.
  • A progress indicator is important or the page might load so fast that the user doesn't visually detect it changed. This can lead to a worse user experience because they don't see the flash of the blank page they're used to when a page load occurs.
  • While forms can be submitted via Ajax, there's no harm in leaving existing form behavior in place where the full site is reloaded after submitting a form.
  • If a particular page needs to change the common elements (header, menu, footer), it should be possible to do that with JavaScript after the PCA content loads.
  • If the success/error indicator is outside the PCA, it may need to be populated and displayed/hidden with JavaScript after the PCA loads.

I'm sure my implementation can be improved, but I'm also curious to see what you think of this idea. I know it's not revolutionary, but it's something I'm considering adding by default to AppFuse and AppFuse Light. Do any Ajax frameworks do something like this out-of-the-box?

Update: Thanks to everyone for the great feedback - keep it coming. I agree that adding history support is a must. I'll try to do that in the next day or two. This post has also been featured on Javalobby and Ajaxian.

Update 2: Added history support.

Posted in Java at Oct 03 2008, 02:33:09 PM MDT 19 Comments

RE: How Open Source is Spring?

Peter Mularien has a very well written post titled How Open Source is Spring?: An Analytical Investigation:

This post is to expand on some of the thoughts I posted on the SpringSource Blog in response to Rod Johnson's excellent description of the SpringSource business model and its commitment to development of open source software.

Now that SpringSource has shown an ability to crank out new product releases on a seemingly weekly basis, I wanted to reflect on where Spring is positioned in the Java open source community, and how open the Spring Core project is to work done by the public.

The hypothesis of my experiment occurred to me when I happened to be reviewing Spring JIRA assignments one day. I was curious whether, following the bug assignments, the majority of development on the "Spring Core" projects (including Spring MVC and what we would consider "classic Spring") is performed solely by SpringSource employees.

Peter's post is near and dear to me because I'm doing a What's coming in Spring 3.0 talk at the Colorado Software Summit in October. The only information I was able to find on Spring 3.0 is from random blog posts and Juergen's presentation. When I give talks about technologies, I prefer to dig in and try them before talking about it. With Spring 3.0's source code nowhere to be found, this is very difficult to do.

I really hope Spring 3.0 becomes available in early October. If it does, I hope to upgrade AppFuse, AppFuse Light and Spring Kickstart. If it doesn't, my talk will most likely be a regurgitation of what Juergen's slides have and that's just not right.

Posted in Java at Sep 19 2008, 09:54:48 AM MDT 14 Comments

Upgrading Hibernate to 3.4.0 and AppFuse for Tapestry 5

Last night I spent an hour upgrading AppFuse to Hibernate 3.4.0.GA. I tried the same thing a week ago, but failed miserably. When Hibernate Core Modules (3.3) (a Maven dependency howto) showed up on the Hibernate blog, I was re-inspired. I discovered some interesting things along the way (at least in my setup).

You need to use JBoss's Maven Repository
The latest Hibernate releases aren't in the central Maven repo yet. If they're not in there two weeks after the release, I doubt they'll be there anytime soon. Best to plan on adding http://repository.jboss.com/maven2 as a permanent repository. As a bonus, you can remove http://download.java.net/maven/2 since JTA is in JBoss's repo.

Javassist is not an optional dependency
If I remove the Javassist dependency, here's the error I get:

java.lang.NoClassDefFoundError: javassist/util/proxy/MethodFilter

Seems reasonable right? What if I add in the dependency on Hibernate's cglib instead?

java.lang.NoClassDefFoundError: javassist/util/proxy/MethodFilter

OK, so apparently you can't switch between Javassist and hibernate-cglib-repack as stated in Hibernate's Maven dependency howto. Of course, I do believe their instructions are correct, they just don't work in my setup. Versions I'm using: hibernate-core-3.3.1.GA and hibernate-annotations-3.4.0.GA.

Not including SLF4J is a bad idea
If you don't include a dependency on SLF4J (and you're using Spring), you get a nice cryptic error message.

Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class 
[org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean]: 
Constructor threw exception; nested exception is java.lang.NoClassDefFoundError
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:115)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:61)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:877)
        ... 48 more
Caused by: java.lang.NoClassDefFoundError
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:164)
        at org.springframework.orm.hibernate3.LocalSessionFactoryBean.class$(LocalSessionFactoryBean.java:174)
        at org.springframework.orm.hibernate3.LocalSessionFactoryBean.(LocalSessionFactoryBean.java:174)
        at org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean.(AnnotationSessionFactoryBean.java:64)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:100)

Hibernate's JPA now uses PersistenceException instead of EntityExistsException
In previous releases, Hibernate's ConstraintViolationException was wrapped in a javax.persistence.EntityExistsException. In Hibernate's EntityManager 3.4.0.GA, it's wrapped in a javax.persistence.PersistenceException.

Of course, these errors could be caused by Spring or Maven, but my hunch is they're more related to Hibernate and it's new more modular dependencies. You can view the full changeset for upgrading Hibernate 3.2.6.ga to 3.3.1.GA via FishEye.

Tapestry 5 version of AppFuse
In other AppFuse-related news, Serge Eby has created a Tapestry 5 version of AppFuse. You can see his alpha-level work in Google Code's tapestry5-appfuse project. I haven't had a chance to take a look at Serge's work yet, but I'm eager to do so. Hopefully we can get it back into the main project sooner than later. As far as Wicket and Stripes support, I haven't forgot about those - just having trouble finding the time and motivation to do the work.

Posted in Java at Sep 17 2008, 09:35:45 AM MDT 12 Comments

[OSCON 2008] Web Frameworks of the Future: Flex, GWT, Grails and Rails

Below is the presentation I'm delivering at OSCON today. Unfortunately, I had to remove slides on GWT and Flex to fit w/in the 45 minute time limit. I hope to expand this presentation in the future, as well as continue to develop the side project I'm working on using these technologies.

Posted in Open Source at Jul 23 2008, 04:25:23 PM MDT 19 Comments

2008: The Year of Beer

Beer In a few weeks, I'm heading to the American Craft Beer Festival in Boston. In July, I'll be attending the Oregon Brewers Festival in Portland (followed by a night at McMenamins Kennedy School). A friend and I just booked flights for Oktoberfest in Munich. A couple weeks after Oktoberfest, I'll be attending the Great American Beer Festival in Denver.

Homer would be proud.

Posted in General at Jun 04 2008, 02:58:37 PM MDT 15 Comments

Why no more than 500 connections?

I recently updated my status on LinkedIn to read:

Matt is determined not to have 500+ connections. Will start removing connections soon.

A couple of days later, I received the following message from a connection:

I noticed the other day you mentioned that you are determined to not have over 500 LinkedIn connections. I'm wondering what the reason is? Not just because LinkedIn shows 500+ after that, is it? As you work for LinkedIn, I assume there's some other reason. I'm interested to know what it is...

I joined LinkedIn May 27, 2003, 22 days after it initially launched. For the first few years, I accepted invitations when I received them. Some folks I knew, some I didn't. When I started consulting for LinkedIn last summer, I had somewhere between 200 and 300 connections. Most of them were people who had contacted me, not folks I had contacted.

One day, I used the import webmail contacts feature to pull in my contacts from Gmail. My number of connections quickly jumped by 100 and it's increased quite a bit since then (mostly due to co-workers from LinkedIn). Of the almost 500 connections I have, I believe there's a good 100-200 of them that are folks I don't know, have never had contact with, and will likely never benefit from being "connected" with.

I guess the main reason I'm planning on trimming my connections is to make my network higher quality. I admit I'm somewhat motivated by the 500+ icon, but it's also a genuine feeling that there's quite a few folks I won't benefit from being connected to. I'm not a LION after all. I believe my LinkedIn network should resemble my real-world network.

What's your opinion? Should I have folks in my network that know me, but I don't know them?

Posted in The Web at Jun 01 2008, 06:40:59 PM MDT 17 Comments