Checking out Hibernate with STS

I have cause to revisit my post about importing a git checkout into Eclipse. I need to take a look at the Hibernate code, which is on github at git://github.com/hibernate/hibernate-orm.git, and given the somewhat convoluted nature of this code, I need an IDE to help navigate it.

Now, I hear that with Eclipse Indigo (3.7), which is included with the latest STS 2.9 (which is what I use), the EGit plugin is included out of the box (which, for the purposes of this post, is what I’m doing – completely stock install). That’s helpful. See, previously, if you wanted to do something with git, you would find no evidence within Eclipse that it could. If you figured “there must be an extension for that” and searched for “git” from the extensions wizard, there would be no hits. Because what you needed to look for was “JGit” or “EGit” – you big dummy. An example of what I consider low discoverability that’s pervasive in Eclipse/STS. But I digress.

At least EGit has had a couple years to bake since my post. I went to File->Import->Git->Projects from Git and put in the URI above. This seems pretty straightforward:

Image

I’m not sure why it parses the URI into Host and Repository path here. Is there some reason you’d want to customize these?

In the next step, I pick the branches from the repo I want and proceed to the “local destination” dialog.

Image

These steps might be somewhat confusing to those who don’t know git and just want to take a look at some code. Since git is distributed, you don’t just get a point-in-time checkout from a repo, you get your own copy of the repo – or as much of it as you want. Basically it’s asking where I want my copy of the repository and checkout to go. The checkout (“initial branch” here) will go in the directory, and the repo will go in a .git subdirectory. “origin” is the name given to the repository I cloned this from, in case I want to sync with that later. That might be kind of obvious to someone familiar with git, but how about some tips for those who aren’t?

My question: why doesn’t this all simply default to being inside the workspace? What’s a workspace for, if not the project contents? As you can see, the default is to create a ~/git directory and checkout/clone the repo there.

Next step, three inscrutable options for how to deal with the resulting project(s) that have been checked out:

Image

OK. These seriously need some explanation. What do these do?

“Import existing projects” gets me nowhere in this case, as it requires Eclipse project descriptors to be included in the checkout, and they’re not. Arguably, they probably shouldn’t be. I just get the error “no projects found” if I try this. But that means I need to figure out myself how to get Eclipse/STS to interpret this checkout properly.

“Use the New Project wizard” is an option I don’t really understand. It just dumps you into the new project wizard you would get by clicking the new project button (generally the first button in the toolbar). This is also where you end up if you click “Finish” instead of “Next” anywhere along the way. I guess I could make use of the directory just created. I  also can’t go “back” and choose another option from here; cancel, and I’m back to square one. In general, I find the “New Project wizard” one of the most confusing things about Eclipse/STS, because there are so many options, many sounding similar yet meaning something completely different, and no explanations of what you can expect to get. Do I really have to go looking for doc that should be a click away? I digress.

“Import as general project” basically just creates a project with the given content and no organization. STS recognizes the different file types, of course, but there’s no concept of where the classpaths begin, how to build and test the project, anything like that – just plain directories with content. This won’t get me to my goal, which is to be able to look up class hierarchies, implementors of interfaces, etc. However, having done this, I can try to configure the project to get it to where STS understands these things.

I’m interested in the 3.6 branch of Hibernate, which is a Maven project (you can tell from the pom.xml – woe betide you in the Java world if you don’t recognize Maven when you see it. The “master” branch seems to be using Gradle). So I can right-click the project and Configure -> Convert to Maven Project.

By the way, let me point out something that didn’t work at all: creating a new project with the wizard “Maven -> Checkout Maven Projects from SCM”.

Image

This is apparently not aware of the EGit plugin, because there’s no SCM protocol listed here (the first box  is greyed out). If I click “Finish” here nothing happens except the dialog exits. I think it would probably work if I added a m2e SCM connector like the link suggests, but how would I know to do that?

Alright, so now I have a Maven project. Right away in the top-level pom.xml I get a “Project build error: Unresolveable build extension: Plugin org.jboss.maven.plugins:maven-jdocbook-style-plugin:2.0.0 or one of its dependencies could not be resolved: Could not find artifact org.jboss.maven.plugins:maven-jdocbook-style-plugin:jar:2.0.0 in central (http://repo1.maven.org/maven2)”. I happen to know what this is about because I know there are a bunch of JBoss dependencies not in Maven Central. How would I know that if I didn’t know? Google, I guess. Fortunately searching for that exact error message gets me right to a StackOverflow question about exactly the same thing, which someone has helpfully solved. I love SO, I just hate that it has to exist. Documentation is always about how to use something the right way, not what to do when something goes wrong. SO fills that gap.

So, add the repository information to the pom.xml – or, better, to my Maven settings.xml (which I had to create since STS is providing Maven in this setup) and on to the next problem. Two, actually (always seems to be the way of it – removing a build problem just uncovers more). These are related to “Missing artifact commons-logging”. A little Google sauce on that turns up this blog post (like the name, kinda like my blog!) about the death of the commons-logging dependency. Gotta love trying to support these old builds from a public ever-changing repo. Problem is, the Hibernate pom (actually the parent pom, which is in a subdirectory! huh?) uses the hack from that article, but the repo supplying the dummy dependencies seems to be down. So perhaps I should try the exclusions suggested by commentors in that blog? I found something that looks handy: in the pom dependency hierarchy, right-click and choose “Exclude Maven artifact”:

Image

Sadly, this doesn’t work:

Image

But here’s another StackOverflow suggestion. This seems to work, after removing the existing commons-logging dependencies and adding those ones in the parent pom, and (finally) right-clicking on the project, Maven -> Update project configuration. The errors are gone, and (I suspect) so is all the Maven-fu I can expect today.

Unfortunately I’m still not at my goal – I just have the Maven nature working now.

Turns out, this wasn’t quite the right path. What I’m looking at here are multiple Maven projects, with interdependencies. There’s no way I’m ever going to get anything useful from this in a single STS project. What I need to do is import these as multiple projects. In the meantime, delete the existing project (but leave the checkout) so it doesn’t get in the way.

So here’s what I do: File -> Import -> Existing Maven Projects and enter the path to my local checkout as the “Root Directory”:

If I select all the projects, they’ll all be created as interdependent workspace projects, each with build path and so forth configured according to Maven.

With lots of errors, of course… thousands, in fact. But let me start with the Maven problems, which are probably the source of the rest. Looks like all of the Maven errors are of the form “Plugin execution not covered by lifecycle configuration: org.jboss.maven.plugins:maven-injection-plugin:1.0.2:bytecode (execution: default, phase: compile)” – with a different plugin each time. I remember the import screen warned about some problems that would need to be resolved later – this seems to be what it was talking about.

Well, much later now, I think the Maven errors were mostly irrelevant. Those were due to the change to the m2eclipse plugin which broke the world for a lot of Maven users in Eclipse. Most of them were things that looked like it was safe to have m2eclipse “ignore” as recommended there. I went ahead and ran some of the goals that looked important (antrun:run and injection:bytecode in hibernate-entitymanager, the latter in hibernate-core) from the command line. Not sure they made much difference. I did Maven -> Update Project Configuration on everything changed and most of the red X’s went away.

I also ran into this problem and crashed a few times just by mousing over the “Window->Browser” menu before adding “-Dorg.eclipse.swt.browser.DefaultType=mozilla” to my STS.ini to avoid it.

At this point, the only problem seems to be that hibernate-entity has a ton of tests with imports like this:

import org.hibernate.ejb.metamodel.Customer_;
import org.hibernate.ejb.metamodel.Order;
import org.hibernate.ejb.metamodel.Order_;

… and then goes on to use these classes with underscores, which aren’t there. Evidently they’re supposed to be generated at some point, but I’m not sure how. I don’t really care about running these tests, just wanted to look at the framework code, so although STS reports 14382 Java problems, I can consider my work done here. Boy, that was easy!

One more note: I went back and added the git SCM connector for m2eclipse to try it out. It worked… but poorly. The way that worked was to select “git” for the scheme, then put in the git:// URI for the project, then wait for a popup to select the projects to import. If I reversed order or didn’t wait, I got either an error or nothing after hitting “Finish”. Hmm… hope that’s better in the next update. And, interestingly… the checkout/repo went into the workspace.

Advertisements

Im-a build me some Spring samples (Part 1: petcare) #fail

Just more examples of commonplace Eclipse/Java things that drive me nuts. I should say up front that the version of Eclipse I’m using is actually SpringSource Tool Suite (STS) version 2.3.2.RELEASE, running on the 1.6.0_20 64-bit Sun HotSpot JVM on Fedora 13.

There’s a trove of Spring sample projects over at https://src.springframework.org/svn/spring-samples/ – very helpful. So I had Eclipse check some out and import them as projects. Funny thing, there seem to be a lot of complaints about XML. I’m getting a little more savvy, let’s see if I can resolve these.

Pet Care

spring-petcare-3.0.xsd

From petcare’s servlet-context.xml, we get the good old “Referenced file contains errors (http://www.springframework.org/schema/petcare/spring-petcare-3.0.xsd).” OK – I’m pretty familiar with that. If you try to go to the URL given, SpringSource’s server redirects you to the home page. Seems the “petcare” schema just didn’t quite make the list with the rest of the framework – I can understand that. But what URL should we use instead?

Well, not surprisingly, the petcare projects contains its own XSD; it’s in /src/main/resources/org/springframework/samples/petcare/util/config/ – so how do I use that as the URL? Well, one way is to use the svn tree from the website; then the schemaLocation is https://src.springframework.org/svn/spring-samples/petcare/trunk/src/main/resources/org/springframework/samples/petcare/util/config/spring-petcare-3.0.xsd. Would have been nice if the project just did that, wouldn’t it? I would think that, distrusting SpringSource not to move/change it again, you could refer to it relative to src/main/resources/META-INF/spring/appServlet/servlet-context.xml as ../../../org/springframework/samples/petcare/util/config/spring-petcare-3.0.xsd (feeling the pain yet?) or copy it to the same directory and just refer to it as spring-petcare-3.0.xsd – but neither of these seems to work on deploy, while the web URL does. There’s a file META-INF/spring/spring.schemas that appears to be intended to specify where to look in the project for the schema, but I’m not sure how it’s supposed to be referred to in Eclipse to make this work.

Here’s a really great error Eclipse has on one of the XML elements that refers to the schema: “- schema_reference.4: Failed to read schema document ‘spring-petcare-3.0.xsd’, because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.” So which is it? Good grief. Would it really be hard to make messages like this actually useful? This is so frustrating.

Amazingly enough, if you try to deploy and you haven’t cleaned this up, Tomcat goes and tries to download the XSD as well and fails if it comes out wrong. So there you have it: your ability to deploy seems to depend on whether the right web sites are up at the right time. I imagine there’s a Tomcat or context.xml setting to disable this behavior.

Spring NamespaceHandler for petcare:resources

OK. So now I’m pointing at the right XSD, but I still have problems with servlet-context.xml. Actually it’s only a warning, but: “Unable to locate Spring NamespaceHandler for element ‘petcare:resources’ of schema namespace ‘http://www.springframework.org/schema/petcare'&#8221; – again with the “Unable to locate” business. That crap sure gets old. Why don’t you give me some kind of clue? Where did you look, where should I look? Actually I think I understand this and it’s trying to say there’s no “resources” element defined in the XSD. But there certainly is, so I don’t really know what this is on about. It seems to work anyway on deploy so I’ll ignore for now.

root-context.xml: Build path is incomplete

On to root-context.xml, another Spring bean file. This has three errors listed. The first two are really confusing: Next to line 22 which looks like this:

<!-- Embedded H2 Database -->

I have the error “Build path is incomplete. Cannot find class file for org.springframework.samples.petcare.users.PetcareAuthenticationFailureHandler”. Next to line 24 which looks like this:

<jdbc:script location="classpath:schema.sql" />

I have the error “Build path is incomplete. Cannot find class file for org.springframework.samples.petcare.users.PetcareUserService”. WTF? Actually Eclipse helpfully gave me a clue below on line 56, which looks like this:

<import resource="security.xml" />

This has the warning “Validation warning occured in imported configuration file ‘src/main/resources/META-INF/spring/security.xml'”. Yes, as it turns out that file has errors on lines 22 and 24, where  they make a lot more sense. But they’re not reported in security.xml; they’re reported against irrelevant lines in root-context.xml, which just includes it. Truly mind-boggling.

Now from this, plus the “Build path is incomplete. Cannot find class file for org.springframework.samples.petcare.util.templating.DefaultStringTemplateFactory” on line 29, I gather the build path is incomplete. But all those files look to be provided by this project and the build paths seem to be set up fine. So what the heck is going on?

At this point I checked my system and noticed that after installing some unrelated things, Fedora has chosen java-1.5.0-gcj as my compiler. I don’t think Eclipse is using this, and theoretically it shouldn’t matter anyway, but I shut down Eclipse, reconfigure alternatives so the Sun JDK is again providing the default javac, restart Eclipse, and clean the project. Somewhere in there, the complaints went away.

page.jsp Type mismatch

Now I’m left with just one actual error in src/main/webapp/WEB-INF/layouts/page.jsp. Only, when I open that file, Eclipse doesn’t list any errors. I have to go down to the “Markers” tab to find it:

page.jsp line 62 Type mismatch: cannot convert from boolean to String

Line 62 is a completely innocuous HTML div. Eclipse is just bonkers. I delete the marker and now my petcare project is free of red Xes. I deploy and it works. That might be enough for some people… but now, what about all those warnings?

Unresolvable warnings

Our old friend servlet-context.xml still has a warning next to <petcare:resources> that says “Unable to locate Spring NamespaceHandler for element ‘petcare:resources’ of schema namespace ‘http://www.springframework.org/schema/petcare'&#8221;. I feel I’ve been as clear as possible about the petcare schema so I really don’t know what more there is to say. So let’s leave that (or delete it).

Under src/main/resources, log4j.xml complains “The file cannot be validated as the XML Schema “/home/luke/Documents/workspace-sts-2.3.2.RELEASE/petcare/src/main/java/log4j.dtd (No such file or directory)” that is specified as describing the syntax of the file cannot be located.” This seems to be universally ignored – as I recall, I saw some bogus explanation as to why it was bad to specify a URL for this DTD. You would think Eclipse could just supply the DTD itself, or find it somewhere in the log4j JAR in my Maven dependencies. I don’t have a clue what to do about this so I leave it.

The final warnings are in src/main/webapp/WEB-INF/views/appointments/calendar.jsp, where Eclipse is complaining about data-* attributes on some HTML tags. As I recall these attribute “extensions” are part of the HTML standard so I don’t know why Eclipse is complaining. No way to shut it up without disabling validation entirely, so again let’s leave it. And that’s it for petcare.

Memory (classloader) leak

BTW, petcare has a big fat memory leak in it somewhere, because after you’ve re-deployed a few times, you get a PermGen error. Nice going. I can use this to hone my memory-leak-debugging skills soon.

back in the saddle… (?)

Hoo boy have I been busy, mostly too busy to track it here. Found some actual contract work – well, if I could just get a signed contract. And also have been exploring Spring for a potential job offer. But my tech-fu has been failing left and right, don’t know what happened!

My trouble started a week ago when I went to my Android hack night and Eclipse on my laptop wouldn’t even bring up any editors. At the time I thought it was somehow related to the STS (SpringSource Tool Suite) I had installed (it’s another eclipse distro) but now I doubt it was related; there had been a number of other system updates and I think some of them caused problems, though I’m still at this date unclear what happened. I installed an entire parallel Fedora 12 system reusing my home directory but not introducing all the rpmfusion/jpackage stuff and it seemed to do better with Android but I ended up monkeying around with .eclipse and eclipse-workspace/.metadata until I’m not sure what I did anymore. All the while switching back and forth between the two OS installs did wonders for my firefox config. I *think* it’ll play Flash again now.

In the midst of all that I was trying to get work done and try out Spring. STS gave me fits, and I’m really not sure how much of it is STS/Java and how much was related to other issues was having. I stopped trying to figure things out on the notebook after a while, but I tried STS on Ubuntu and on WinXP and the best I could get it to was that it would build the examples and deploy them to tomcat, but this might not work after the first time, and half of my projects were riddled with all kinds of dependency problems. Dependencies in Java are a nightmare. I’m sure if I sat in a cube next to some gurus for a few days, they’d get my system in shape. But having to figure it out alone is infuriating.

But the fun did not end there. My laptop started acting really odd yesterday; stopped being able to open applications and such. I rebooted and the shutdown had lots of complaints about stuff that was refusing to unmount and such. After reboot I couldn’t log in graphically. I got to a place where it was trying to login and stuck, and I couldn’t switch to any consoles so had to do a hard stop, and of course when it rebooted I was nailed with fsck (for BOTH installs of Fedora now). Then I was fiddling with it and started getting messages about “can’t modify (foo) – read-only filesystem” – this was for BOTH the OS and home partitions. From what I could gather in /var/log/messages, the OS started having problems with the filesystems and just remounted everything to read-only – have never seen this before. I rebooted (more scary umount msgs) and applied some Fedora updates, hopefully those may improve things, or I may just have a hardware problem and need a new drive or something. That’s doable but what a pain. I also noticed on the latest reboot that firefox is spawning off numerous gtk-gnash instances that burn CPU for two flash movies in my tabs that I’m not even playing. Killed them all but that really should not be happening. So not too confident in laptop still :-(

Agenda for today: root my old G1, try out CyanogenMod on it, and see if I can get androidscreencast going.