Matt RaibleMatt Raible is a Java Champion and Developer Advocate at Okta. developer.okta.com

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.

AppFuse a top 10 java.net project?

AppFuse I don't know if it's really a top 10 project, but it gets lots of hits, accesses and mail traffic. Nice! I'm willing to bet it's the cool logo that's the source of its popularity. ;-)

BTW, I'm giving a talk on AppFuse at Denver's No Fluff Just Stuff in two weeks. If I can finish up the "appgen" tool by then, the talk could be a lot more fun as the demo would be short and sweet. I doubt it'll happen though. I'm knee deep in creating a version of AppFuse Light that showcases how to use Spring with Hibernate and your choice of web framework: Struts, Spring, WebWork, Tapestry or JSF. I hope to release it sometime this weekend or early next week. Next week (and likely the week after), I have to write Chapter 10 of Spring Live. That leaves almost no time for creating the next cool tool. Who knows though - it might be easier than I think - especially since Lance submitted a good start.

Posted in Java at Oct 29 2004, 09:49:17 PM MDT 2 Comments

Trails - like Rails, but with Tapestry, Spring and Hibernate

I've been thinking about Rails ever since I wrote a post about it on Monday. The main reason is because of Dion's comment:

Matt - You should follow the lead and do a video of setting up a simple app using AppFuse.

This might sounds like a good idea, but if I did it right now in AppFuse's current state, it'd be a disaster. The reason? Because you have to manually create a whole bunch of classes to do CRUD on a database table. Here's a list of new classes needed for adding a new "person" table.

  • model.Person
  • dao.PersonDAOTest
  • dao.PersonDAO
  • dao.hibernate.PersonDAOHibernate
  • service.PersonManagerTest
  • service.PersonManager
  • service.impl.PersonManagerImpl
  • webapp.action.PersonActionTest
  • webapp.action.PersonAction
  • web/pages/personList.jsp
  • web/pages/personForm.jsp

The last two JSPs can be generated, but that's still a buttload of classes (9) just to CRUD (and test!) a database table. Not too mention all the files you need to edit for Spring and i18n.

  • dao/hibernate/applicationContext-hibernate.xml
  • service/applicationContext-service.xml
  • test/web/web-tests.xml
  • web/WEB-INF/classes/ApplicationResources_en.properties
  • web/WEB-INF/menu-config.xml

Result: to CRUD a database table using AppFuse you have to create 11 new files and modify 5 existing files. 16 files. What a beotch, huh? If I made a video of this - it'd be 20 minutes long! While this might make AppFuse look silly, it's really more of a symptom of the patterns we have in J2EE and how we're supposed to architect our apps. 3 tiers, test-driven, loosely-coupled and internationalized. Of course, if I was focused on fast and efficient, I could do this all with 1 JSP and JSTL's SQL tags. Everyone would slap my hand for not following patterns, but I'm willing to bet it'd work just as well and be just as fast. But I digress.

There have been a fair amount of requests (and some patches submitted) to generate and modify all of the files listed above. For the most part, I've frowned upon adding such a feature because I think if folks can run "ant generate -Dmodel=Person" - they'll end up with a whole bunch of code that they know nothing about. Sure there's the tutorials, but folks will quit reading those. Instead, they'll create a whole slew of POJOs (maybe even using Middlegen) and run "ant generate" on all 50 of them. Poof - now they've got 550 new files to maintain. Talk about a maintenance nightmare. Even worse - a support nightmare for me.

Nevertheless, if I wanted to create a cool video for AppFuse, I'd spend a few days writing this code-generation engine. Then I could show how you could create the data, service and web layer (including UI) in a matter of seconds. It'd be cool and folks would dig it. I'm still considering it, but I'm also leary of the resulting support fiasco. Maybe I could just say "use at your own risk". ;-)

A while back, I saw Erik Hatcher suggest a better solution than code-generation. I can't remember what he called it, but it was something like "meta-data dynamic rendering". The idea is that your application reads the metadata of a table (or POJO) and renders the appropriate UI for it. I loved the idea as soon as I heard it. I've always wanted a way to dynamically render the UI rather than writing HTML. Of course, I still want the ability to edit the templates and HTML since I fancy that sort of stuff. I don't like writing HTML for each row in a form, but I do like tweaking the HTML and CSS to look good.

Earlier this week, I saw the concept in action with Rails and its demo. IMO, something like Rails would never fly in Java because it appears to be tightly coupled to the database and only MySQL, PostgreSQL, and SQLite are supported. The Java community always seems to pride itself on database abstraction, partly due to JDBC and its ability to connect to anything that has a JDBC Driver. Ruby will probably catch up someday, but right now it appears to be looking for something like JDBC.

Then along comes Trails, which made me smile earlier today when I first read about it on the tapestry-dev mailing list.

I've been working on a project called Trails that uses Tapestry quite heavily and I thought it time to start soliciting feedback. Trails is a domain driven development framework that uses Tapestry, Spring, and Hibernate. Trails is very much in it's infancy, but the current version is functional and should give people a rough idea where I am heading. It's my first real forray into Tapesty and I have really found Tapestry a joy to work with.

Trails is very much like Rails, except that it doesn't talk directly to a database table. Instead, it talks to your domain objects that you mark up with XDoclet/Hibernate tags. To test it out, I dropped a User.java file into the org.trails.demo package, marked it up with XDoclet and deployed. It didn't work at first because the .hbm.xml files are explicitly listed in Spring's applicationContext.xml. I changed the "sessionFactory" bean to use the following and wammo - success! I could list and CRUD the table that my User object was mapped to.

  <property name="mappingDirectoryLocations">
    <list>
      <value>classpath:</value>
    </list>
  </property>

Trails is very cool, and I'd love to incorporate it into AppFuse or Equinox. Does an LGPL license allow me to do this? The one problem I can see with adding it is that it's specific to Tapestry and Hibernate, which doesn't always suite folks. I think developers might be willing to change because this solution will vastly improve their development productivity, but who knows. I think the best solution would be to offer this option in AppFuse/Equinox, but also offer the current manual and code-generation options. The holy grail would be the ability to plug in iBATIS or JDO instead of Hibernate. In addition, using Struts, Spring, WebWork or JSF instead of Tapestry would have folks clammering to use this stuff.

Mad props to David Heinemeier Hansson and Chris Nelson - you guys are developing awesome software.

Posted in Java at Oct 29 2004, 01:50:30 AM MDT 22 Comments

Fun with Log4J and JBoss

I've had the pleasure of working with JBoss (3.2.5) and an AppFuse-based application for the past week. It was fairly easy to setup thanks to Rick Hightower's instructions. AppFuse uses commons logging (like many of its open-source dependencies), but uses log4j to control what gets printed to where. By default, it changes Hibernate and Spring to use WARN and the application classes to use DEBUG. For most containers, this works great. Drop in the WAR, or package it in an EAR and voila - your logging statements show up in the console. Not so with JBoss. Spring and Hibernate use INFO and I can't get any debug statements to show from my classes.

I shouda known this would be a pain since Rick wrote "Setting up logging is a pain in JBoss. Don't mess with the console log... it misbehaves. Create a file logger and tail it.". Is this the best practice for logging with Log4J in JBoss?

You'd think printing to the console would be easy. This wiki page even makes it look easy: change your log4j.properties to log4j.xml and add a <class-loading> snippet to your jboss-web.xml. Unfortunately, I get this nice error message:

00:21:17,593 WARN  [DeploymentInfo] Only the root deployment can set the loader repository, ingoring
 config=LoaderRepositoryConfig(repositoryName: log4j.config:loader=appfuse.war, repository
ClassName: org.jboss.mx.loading.HeirarchicalLoaderRepository3, configParserClassName: org.jboss.mx.l
oading.HeirarchicalLoaderRepository3ConfigParser, repositoryConfig: java2ParentDelegation=false)

Any ideas are appreciated - it seems wrong that I have to write to file just to tail it so I get the same console behavior I get with other servers.

Posted in Java at Oct 29 2004, 12:12:15 AM MDT 7 Comments