Matt RaibleMatt Raible is a writer with a passion for software. 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.

Braindump: Roller, Hosting and Wrox

I have a lot of things I want to mention, so let's just get right to it.

Roller should bundle Moblogger
It'd be cool if Roller bundled Russ's Moblogger as part of the application. It'd be pretty easy, all we'd need to do is slap a UI on it's config file - possibly put the config into a database, and maybe even use Roller's "page" feature for the e-mail templates. Then we'd have to figure out a way to start Moblogger's thread in the background and possibly do one thread for each user.

Roller Plugins
Should Roller add a Plugins feature like Blojsom has? Why should we? If we should, maybe we should just re-use an existing plug-in API - i.e. Struts' or Blojsom's. What would make a good plugin? Is this just a fancy name for a feature that can be turned on/off (i.e. comments).

Struts Menu for the Editor
I hope to add the ability to choose different menu types in Roller's Editor UI. First, I'll have to integrate Roller's tabbed menu as a displayer for struts-menu [demo]. The CoolMenu's displayer will work great (and require less mouse clicks). I mention this in hopes of making Lance and Dave aware of any schema changes that need to be made to support a user-selectable menu type. I'll also need to add the ability to specify struts-forwards in the menu-config.xml (not implemented yet in struts-menu).

This site and my provider
This site was down a lot today - probably because of all the hits from javablogs.com (just put Hibernate in your title). I noticed that Simon and Sam's sites were down as well. This leads me to believe that my kgbinternet.com is not up to snuff. Dave and Lance seem to never have issues with Roller crashing - so why am I? Please recommend any hosting providers that offer private Tomcat instances (preferrably with lots of RAM and disk space).

What's up with Wrox and Professional JSP 2.0
Who knows... I haven't heard a thing, from anyone. Think I'd get anyone's attention if I slapped both of my chapters on this site - free of charge? I doubt it. I might just do that if I don't get any feedback in the next week or so. Are they gonna sue me for the pocket change they paid me to write the chapters?

Now I'm going to assign this to my Java category and see if all you java.bloggers can crash this site again. ;-)

Posted in Java at Apr 29 2003, 11:20:43 PM MDT 8 Comments

Hibernate Upgrade (1.2.4 to 2.0 rc1) Redux

My last upgrade from Hibernate 1.2.x to 2.0.x was a little rocky, so I'm going to document it again today - this time with a Hibernate 2.0-enabled version of XDoclet, and code samples from last time. Today I'm upgrading from 1.2.4 to 2.0 rc1.

1. First, I downloaded Hibernate 2.0 rc1. BTW, I also updated to the latest version of XDoclet from CVS.

2. Next, I copied it to my project's lib directory, deleted bin, doc, and src directories. The only files I need are hibernate2.jar and (in the lib folder) c3p0.jar, cglib.jar, dom4j.jar, jcs.jar, jdom.jar and odmg.jar. One thing to note is with Hibernate 1.2.x, I didn't need dom4j.jar, jdom.jar or cglib.jar in my deployed WEB-INF/lib folder. However, with the new version, I did need to include them.

3. Then I updated lib/lib.properties and began changing my code with gool ol' Homesite.

4. Hey, step 4 is the same as last time! Edit build.xml file to pick up the new DTD. I changed <hibernate/> to be <hibernate validatexml="true" version="2.0"/>.

5. Using HomeSite, I did s/cirrus.hibernate/net.sf.hibernate/g for all my .java and .xml files. Don't forget to change your log4.properties and hibernate.properties files.

6. In hibernate.cfg.xml I changed cirrus.hibernate.sql.OracleDialect to net.sf.hibernate.dialect.OracleDialect. I also updated the DTD to 2.0 and moved all properties inside the <session-factory> element. Here's a sample hibernate.cfg.xml file from struts-resume.

7. In my ServiceLocator.java class, I changed the following from (this is so JUnit Tests can run w/o JNDI):

Datastore datastore = Hibernate.createDatastore();
datastore.storeClass(package.MyClass.class); // lots of these
sf = datastore.buildSessionFactory();

To:

sf = new Configuration().addClass(MyClass.class) // lots of these
                        .buildSessionFactory();

8. Time to bring Eclipse to the table. I refreshed the project and added the new hibernate2.jar to the "Java Build Path."

9. In my StartupListener.java (which initializes Hibernate for Tomcat), I changed the following code:

// Configure Hibernate.
try {
    Hibernate.configure();

    if (log.isDebugEnabled()) {
        log.debug("Hibernate configuration completed.");
    }
} catch (HibernateException h) {
    log.fatal("Error configuring Hibernate!", h);
}

To:

try {
    SessionFactory sf =
        new Configuration().configure().buildSessionFactory();

    if (log.isDebugEnabled()) {
        log.debug("Hibernate configuration completed.");
    }
} catch (HibernateException h) {
    log.fatal("Error configuring Hibernate!", h);
}

10. Changed all instances of readonly="true" to inverse="false" inverse="true" for XDoclet tags. Also changed role to name.

11. Removed length attribute from any <key-property ... /> elements in my .hbm.xml files. These were rudely put there by the ReverseGenerator. Not all my mapping files are generated by XDoclet, if I have one with a composite-id, I just create the mapping file manually. I also had the change the DTD manually in these files.

12. In my build.xml, I changed the SchemaExport class from net.sf.hibernate.tools to net.sf.hibernate.tool.hbm2ddl.

13. OK, here goes, my first attempt at compiling (honestly!). Darn - I forgot to save StartupListener.java - trying again (this time with "ant clean" first). Sweeeet - it worked!

14. Hmmm, some log messages I wasn't expecting. I forgot to change my log4j.properties file from cirrus.hibernate to net.sf.hibernate. I'll add this above (step 5) to make this how to more accurate.

15. Running persistence tests - since I keep my Oracle driver (ojdbc14.jar) in ${hibernate.dir}/lib, I had to move it to the new directory. Now this is a strange error:

[junit] 2003-04-29 13:14:50,968 INFO [main] Configuration.addClass(264) | Mapping resource: com/
.../persistence/ChangeRequest.hbm.xml
[junit] 2003-04-29 13:14:51,234 ERROR [main] XMLHelper$ErrorLogger.error(37) | Error parsing XML
: XML InputStream(19)
[junit] org.xml.sax.SAXParseException: Attribute "name" is required and must be specified for el
ement type "param".

My guess is that it's being caused by:

<generator class="sequence">
    <param>cr_master_sq</param>
</generator>

After reading the Hibernate2 Porting Guidelines, looks like I need to add a name attribute. Didn't the exception tell me that! ;0)

I'll update this post when I figure out the answer to my question on Hibernate's forums...

Update: I had to 1) upgrade my XDoclet JARs, and 2) replace the following XDoclet tags:

* @hibernate.id column="cr_id" unsaved-value="null"
*  generator-class="sequence" generator-parameter-1="cr_master_sq"

with:

* @hibernate.id column="cr_id" unsaved-value="null" generator-class="sequence" 
* @hibernate.generator-param name="sequence" value="cr_master_sq" 

Now I'm experiencing this issue.

Update 2: I discovered (from Gavin) that readonly="true" is the same as inverse="true". I've updated step 10 above, and now my upgrade is complete!

Posted in Java at Apr 29 2003, 02:52:07 PM MDT Add a Comment

My JVM doesn't like javablogs.com

Whaddya know, I write a popular post on javablogs.com and this site ends up crashing for a few hours. Here's the cause:

Unexpected Signal : 11 occurred at PC=0x403B4304
Function=(null)+0x403B4304
Library=/usr/java/j2sdk1.4.1_01/jre/lib/i386/client/libjvm.so

NOTE: We are unable to locate the function name symbol for the error
      just occurred. Please refer to release documentation for possible
      reason and solutions.

Lovely...

Posted in Java at Apr 29 2003, 02:49:24 PM MDT Add a Comment

My understanding of CVS

I've been using CVS for a couple of years now, but only recently have I been responsible for tagging and branching. Dave is using the branching feature on Roller, and we're using it at our day job. Here's how I think it works - please correct me if I'm wrong.

When you create a branch, you can continue working on that branch - providing you check it out. This means that you cannot have HEAD checked out and update from the branch. Or can you? I tried this with Roller a couple night ago, and I don't think I got the 091_BRANCH. However, last night when I tried to check stuff in, it said I was on a branch. Wierd.

At work right now, I've created a 2.0 branch, and we're working on this to fix bugs in our beta release. The other day, I checked out HEAD, and did a merge from the 2.0 branch. Then I created a 2.0.1 branch. When we're with 2.0 and we make it a final release, I'll do another merge with HEAD. Is this how you do it? Do you work on a branch and merge/re-tag every few days? It'd be cool if checking in a file on a branch automagically checked it into the HEAD.

Posted in Java at Apr 29 2003, 10:58:26 AM MDT 3 Comments

Hibernate now uses JIRA

Hibernate now has a JIRA instance setup. I must say, the customized UI looks great Mike. What ever happened to the JIRA instance you were going to setup for the Display Tag Library project?

Posted in Java at Apr 29 2003, 10:42:24 AM MDT Add a Comment

iPod: Glad I waited

New iPod Thanks to Kurt, I decided to wait on my purchase of an iPod. And boy am I glad I did - I was going to get a 5 giger for $299 and now I can get a 15 giger for $299! Sweeeet! Now I just have to figure out how I can use the shared drive on my XP machine as a music repository for iTunes. Importing songs across my network takes waaayyy too long.

Posted in Mac OS X at Apr 29 2003, 07:38:17 AM MDT 6 Comments

Validation vs. Business Logic

In the manuscript I'm reading, I just ran into a diagram and overview of a layered architecture - and all of a sudden, it hit me. At work, most of our business rules are being implemented by Struts' Validator framework. In the case of indexed properties and more complicated rules, these reside in the validate() method of our action forms. So it's interesting to me that I'm using a business delegate to perform my business logic - when in actuality, all my delegates are doing is copying properties from a POJO to an ValidatorForm. So this begs the question - shouldn't validation (a.k.a business rules) be done wherever it is most convenient rather than only in the domain layer? Oh yeah, and most of this is just validation - our real business rules (comparing data for validation) takes place in Oracle stored procedures. And you know what - it works great!. So my opinion is - do whatever is easiest and makes the most sense.

Posted in Java at Apr 29 2003, 06:18:27 AM MDT 6 Comments

Hibernate Book Review

I started doing a book review for Manning this morning. It's called Object/Relational Persistence in Java, Practical O/R Mapping with Hibernate, by Christian Bauer and Gavin King. Once again, I find myself in a time crunch with a publisher - at least I'm not writing this time. The task: read/review and critique 105 pages by tomorrow. Shouldn't be too bad, I'd better get cracking! I'll let you know what I think when I'm done.

Update: Sweet - only 86 pages (the rest is just headings). I'm halfway done. Mostly O/R Mapping concepts and comparing database types (i.e. relational vs. object-oriented) to this point. Next is mapping strategies - I hope to learn something here.

Posted in Java at Apr 29 2003, 05:46:01 AM MDT 7 Comments

Adding Cool Comments to Roller

Cool Comments (a.k.a. Twisty Comments) have been added to Roller's CVS. Grab it if you're brave and help me work out the bugs. I've published a how to on Roller's Wiki. It should work on IE 5.5+/Win and Mozilla/all (what a great browser). Doesn't seem to work on Safari, Camino or Opera, which is fine as it degrades nicely. My degraded comments page needs some work though - all the items in my menu are centered. Oh well, must be a missing <td> or some other closing element - I'll deal with it later.

Posted in Roller at Apr 28 2003, 10:25:53 PM MDT 5 Comments

Cool Comments have arrived!

I got the idea the cool comments you now see from Joe Hewitt. It wasn't too bad to implement, but there's still lots of quirks. Many of which you can see. The hardest part was figuring to implement XML loading in Mozilla. Joe is using the following method:

gMediaDoc = document.implementation.createDocument("", "media", null);
gMediaDoc.addEventListener("load", onMediaLoaded, false);
gMediaDoc.load(aURL);

Which works great when the file is on a filesystem, with a .xml extension. I couldn't get Roller to accept a .xml for my comment page's "link" attribute, so I had to resort to a lot of web research, and I came up with the following:

gMediaDoc = document.implementation.createDocument("", "", null);
var xmlHttp = new XMLHttpRequest();
xmlHttp.overrideMimeType("text/xml");
xmlHttp.open("GET", aURL, false);
xmlHttp.send(null);
gMediaDoc.loadXML(xmlHttp.responseXML.xml);
onMediaLoaded();

The loadXML method is provided by Erik Arvidsson's XML Extras. Thanks Erik! There's quite a bit of work to enable inline comments, but I promise to document a how to before it's released to the general public. Here's some problems I hope to fix before that.

  • Alignment - it'd be nice if I could make the div in-line, so I could put a comments link as before - with other text on either side of it. Either that, or make it inherit the parent's text-alignment. It'd be cool if the pictures below had the comments link right below them.
  • URL Prefix - I suppose I could pass in the context + username to solve this one. While it was working normally for me to use $userName/comments for the URL while developing this, I had to use "/page/rd/comments" on this site. I think it's something to do with the <base href="" /> being set.
  • Loading - it takes a few seconds for the templates to load. If you click on the comments link before they've loaded, you'll get a JavaScript error, and be routed to the default comments page. The window's status bar will say "Done initializing comment templates..." when comments are ready for action.
  • No Preview. I don't think this is a big deal, but it probably wouldn't be too hard to add.
  • Missing label from "Remember Me" checkbox. I'm not sure why this is happening, but the text is there!

That's all the enhancements I can think of for now. Tell me what you think and feel free to give these suckers a test drive.

Update: Strange - I'm seeing some errors that I didn't earlier. In IE6/WinXP, I get a JavaScript error ["Access is Denied" error (Line 149, Char 5)]. Also, I can see the "Remember Information" label here, whereas I couldn't on the machine I implemented this on (Win2K/IE6). Strangely enough, Julie's machine is Windows 2000/IE6, and these errors occur on hers as well. Looks like I have a lot more work to do!

Posted in Roller at Apr 28 2003, 06:22:43 PM MDT 13 Comments