When Does an HQL Typo *Not* Cause A Parse Error?

I found something interesting at work yesterday. One of our developers mentioned that when he called a certain method with various sets of parameters, he wasn’t getting back what he expected to get back, based on what he knew was in the database. I put on my sleuth hat and began my investigation.

We use Hibernate for our database layer, and we prefer to use the @NamedQuery annotation to store our queries with the entities they represent. This works out very well for us. But back to the problem. I quickly got to the appropriate .java file and inspected the query. (Obviously I’ve changed the class names, but this is essentially what I found in the file.)

select distinct f
from Foo f
left join fetch f.bar
left join fetch f.baz
lef join fetch f.plonk
where f.id = :fooId

Now, do you notice the typo? Check out line five. It says “lef” instead of “left.” When I first saw this, I thought to myself, “How can this even get parsed by Hibernate into SQL, let alone return any results.” We all work in a large room together, so I mused out loud about this problem. One of our other Really Smart Guys™ came over to have a look. He saw the typo, thought for a second and said, “‘lef’ is being treated as an alias for f.baz on the previous line.” And sure enough, he was right. Just as on the second line where you see “from Foo f,” that ‘f’ is an alias for the entity called Foo. We could have put aliases on each “left join” line, at each line’s end, had we wanted or needed to. By misspelling “left” on line five as “lef,” we unintentionally slapped an alias on the join that is on line four. Even though the query is split across multiple lines here, the HQL parser would see it as one continuous string, and after passing by “fetch f.baz” the next token it would see would be “lef,” which it would interpret as an alias for “f.baz.”

So, as far as parsing the query and translating it into SQL goes, everything is just fine. But there is still a problem caused by the misspelling. Since the parser decided that “lef” was actually an alias, the next bit that it sees is “join fetch f.plonk” which results in a regular inner join, instead of the outer join we really wanted. What this means is that for records in the Foo table who can’t be joined to records in the Plonk table, either because the key is null, or there just isn’t a record in the Plonk table that matches, those records will be excluded from the result set. That’s the behavior our developer was seeing. Changing “lef” to “left” made the whole thing work and the developer got the results he needed.

I’m Digging Java Again

I first started doing Java back in 1995. That’s quite a long time ago. Once I got going, I wrote Java code every single day, for thirteen years. I co-authored a Java book, gave talks on Java and was an all-around, Java Guy™. And sometime around 2006, I got bored with it. Completely and totally bored. I was a one-man shop at a small company, my code was running just-fine-thanks-very-much, and I didn’t feel like doing anything new with it, at all. I was more interested in Ruby and, to a lesser degree, Rails, so Java changes didn’t really interest me. And thus, I failed to notice some really cool stuff that was going on in Java-land.

In June of this year I joined a new company that is doing some rather advanced Java work. I had to get current, tout de suite, and in so doing, I’ve really gotten interested and engaged again. Spring and Hibernate have really changed from the older versions I was using, and so has JUnit. All for the better, from what I can tell.

And with this renewed interest, I’ve bought my first new Java books in over 3 years. I bought Effective Java (2nd Edition) to replace my first edition and Java Concurrency in Practice, because I heard good things about it. So far, I’ve read about 2/3 of  Effective Java. I used to buy Java books all the time. I have tons of them. But when I got bored, I stopped shelling out the cash on the Java books.

Java-land is still a very nice place to play. Sometimes you have to get an outside perspective to realize that.

Strange Obi-Wan Error

I was doing some JDBC today and I forgot that column indexes are 1-based instead of 0-based. It took me a while to figure out what was wrong since the exception message I kept getting was

java.sql.SQLException: Column Index out of range, 0 > 11.

Despite the fact that zero is not, in fact, greater than 11, I checked to make sure I had used < and not <= in my loop because I thought I was going beyond the maximum index… but I wasn’t. The problem was that I wasn’t even getting to the first index! Then I remembered that I started my loop at 0 and that JDBC ResultSets start indexing at 1. Changing it to 1 fixed the problem, but the error message is wrong. It should have told me that 0 was less than 1 or, more helpfully, that ResultSet indexes start at 1…

Can Someone Help With These Eclipse Files?

Is anyone familar with the format of the files in .metadata/.plugins/org.eclipse.core.resources/.projects in the workspace of Eclipse 3.0? I have an Ant task that uses the .classpath file of a project, along with the JDT preferences to build an Ant classpath for a project with an external build file, and I’m now trying to support projects that depend on other projects. I can see from the .classpath file which projects are referenced, either as a “src” type or a “lib” type, depending on how you added it, but I need to actually FIND those projects and get their build info.

I poked around in my workspace and discovered the directory I mentioned above. For each project that Eclipse knows about there is a subdirectory for it. Inside each subdirectory is a file called .location. I can see by looking at this file with a hex editor, that it does indeed contain the full path to the project. But it’s a binary file, and I don’t know the format. Is it documented anywhere?

I also did a little poking around the Eclipse API. I found a ResourcePlugin which sounded useful, but experiments from within Jython were fruitless. I would also like to avoid hooking into the Eclipse API since I’m trying to support multiple versions of Eclipse, but if that’s the only way to get to the data, I’ll do it.

The question, then, can be broken down into three subparts:

  1. Does anyone know the file formats?
  2. Does anyone have a code snippet of using the proper Eclipse API outside of Eclipse to get to the info in those files?
  3. Does anyone have a better solution to this problem?

Since I’ve taken down the writeback feature of this blog, thanks to certain miscreants, if you have a suggestion, please email it to joey@joeygibson.com. Thanks.

Free Eclipse Classpath Ant Task

This software is no longer supported! I have neither used nor updated this software since I originally posted it, back in 2004. You are welcome to both the binary and source versions, but I no longer do anything with it or support it. If you need something changed, you will have to do it yourself, using the source. Sorry, but after I released it, I realized how little I really needed it, and thus stopped using it.

I’ve just released version 1.0 of a free Ant custom task to make it a little easier to work on a project using both Ant and Eclipse. What this task does is read the .classpath file that Eclipse uses to maintain your project’s classpath, combines that with your Eclipse preferences to expand classpath variables and then creates a path-like structure in your Ant project that you can compile against.

I wrote this because I use Eclipse and I always also have a build file. Keeping the two in sync, classpath-wise, was always a hassle. Now I can simply update the classpath inside Eclipse, and whenever I do an Ant build it will automatically be in sync.

I wrote it against Eclipse 3.0 M8 originally. Then I upgraded to M9 and it stopped working. So with a bit of futzing about, I got it to work with both 3.0 versions and 2.1.3, all three of which keep the preferences file in completely different places with completely different names. But that’s taken care of now. I have also tested on both WindowsXP and Linux, but more on XP than Linux.

To use it, drop the jar file (plus jdom.jar if you don’t already have it) in ANT_HOME/lib. Then taskdef the task

  <taskdef resource="com/joeygibson/ant/eclipseclasspath.properties"/>  

Then call the task. There are several optional attributes, but if you want the classpath to end up in a path called “classpath”, then you can probably get by with just this

  <eclipsecp workspace="/home/me/workspace"/>  

If you are on Windows, and using Eclipse 3.0 M8 or later and you keep your workspace in C:/Eclipse/workspace then you don’t even have to do that much. You can get by with

  <eclipsecp/>   

Once you’ve executed the task, just reference the newly-created path from your javac task or anything else that takes a path as an argument.

You can read more about it in the README.txt

I’ve got several downloadable versions available, in both zip and tar.gz formats, with and without source, and with and without jdom.jar. If you use it and like it/don’t like it/have suggestions, please let me know.

Downloads
Binary only ect.zip
ect.tar.gz
Binary w/ JDOM ect-with-jdom.zip
ect-with-jdom.tar.gz
Source only ect-src.zip
ect-src.tar.gz

I’ve heard there are other tools out there that do this, but I didn’t find them, so I wrote my own. Please email me with any comments you have about it.

Ant Talk At CJUG

I want to thank the folks at CJUG for having me up last night to speak on Ant. I thought the talk went well, though I did run long. I must say it’s rather embarrassing to discover that your presentation, which is supposed to fit in about an hour and a half, in reality needs three hours to be done right… I need to pare it down so this doesn’t happen again. Those in attendance didn’t seem to mind too much, and everyone stuck around a bit longer than planned, which was nice to see.

What I’d really like to do is to extract a subset of the slides into a smaller presentation, yet still have them linked so that I would only have to revise the slides in one PowerPoint file instead of two. Does anyone know if that’s possible?

I’m Presenting at NFJS: Atlanta

If anyone will be in or around Atlanta, GA, October 24 – 26, you should think about attending the Atlanta Java Software Symposium which is part of the No Fluff, Just Stuff symposium series. I’ll be presenting a session entitled “Scripting on the JVM” in which I will present various scripting languages like Python and Ruby running on top of the Java virtual machine and trying to explain why that’s cool. The session abstract is located on the sessions listing page; I’m about 1/3 of the way down the page.

I attended this symposium last year and had an excellent experience. The ratio of useful information to vendor-specific sales-weasel crap was extremely high, which is a good thing. I wrote about it in the February Java Developer’s Journal if you want to read about it. There is also a review of one of the other symposia in the series in the current issue.

I’m really looking forward to presenting at it this year’s symposium.

Java Regex APIs and Quoting

I’ve just been digging through the J2SE 1.4 regex stuff, and every time I have to do regex work in Java I keep thinking how much easier it is in other languages. Specifically I’m talking about the clunkiness of the various regexen APIs in Java and the requirement to double-backslash regex operators. We need a better way. Ruby and Perl both have native regex support built in to the language, so the backslashes are just fine. Python, which doesn’t have native regex support (it’s in the library), does have “raw” string quoting, which allows you not to double-up the backslashes. So what I have to write like this in Java:

1  Pattern p =
2      Pattern.compile("(\(\d+\))?\s*(\d{3}\s*\-\s*(\d{3})");
3  Matcher m = p.matcher(my_string);
4  if (m.matches())
5  {
6      ...;
7  }

or

1  if (Pattern.matches("(\(\d+\))?\s*(\d{3}\s*\-\s*(\d{3})", my_string))
2  {
3      ...;
4  }

looks like this in Python:

1  if re.match("((d+))?s*(d{3}s*-s*(d{3})", my_string):
2      ...

and could be even more easily written in Ruby thus:

1  if my_string =~ /((d+))?s*(d{3}s*-s*(d{3})/
2      ...
3  end

See the difference? The built-in regex support is really nice and the ease of quoting is a beautiful thing. I doubt that we’ll ever see either of these in Java since they would certainly be considered non-trivial to add.

J2SE 1.4.2 + WLS 7.0 + weblogic.ejbc = Problem

I discovered something interesting the other day at the office. We have a guy who has been unable to build a certain entire jar of entity beans ever since he started working there and I had only given it scant thought as to why. I knew that I had had no problems… So he came by my office on Wednesday and I said “OK. Let’s figure this out.” I ran our Ant build file that is specifically used for building this particular jar full of entity beans and got the same errors he was reporting. Odd, thought I. The errors being reported by ejbc were that the compiler couldn’t resolve symbols with names like Foo$ValueObject. That was odd since that looked like the inner classes defined in each of the entity beans were not there. But looking at the classes directory, those classes were definitely there. What was really odd was that simply dropping back to J2SE 1.3.1, or even 1.4.1 worked.

For reference, we have a group of entity beans that each have a nested class called ValueObject. (I don’t particularly like that, but they’re there nonetheless.) Essentially we have 80 entity interfaces that follow this basic pattern:

public interface Foo extends EJBLocalObject
{
   ...

   public ValueObject getValueObject()

   public static class ValueObject
   {
       ...
   }
}

and then 80 entity bean classes that actually implement the getValueObject method.

It was at this point that I started looking at that “$” in the class name. It then hit me that the code should be using a “.” between the outer and inner class names, not a “$”. But the code where the error was occurring was generated by ejbc. I’ve tried this now with WLS 7.0 sp2 and sp3 and the results are identical.

Even though I’ve not been able to find this documented in the release notes of J2SE, it would appear that versions prior to 1.4.2 allowed code to specify an inner class using a dollar sign, even though it was not technically correct, and that 1.4.2 has stopped being lenient in this regard. Yes, I know that WLS 7 is not officially supported with 1.4.2… I haven’t tried with WLS 8 yet; I would assume that since it is supported with 1.4.2 they’ve changed the code generation routines inside ejbc.

So the moral of the story is that if you find yourself needing to run WLS 7 with J2SE 1.4.2, and you happen to have entity beans that you need to run through ejbc, first run your build file for those entities using J2SE <= 1.4.1, and run everything else under 1.4.2.

Eclipse 3.0 M2 Is Out

I just got the notice that Eclipse 3.0 M2 is now available. I’ve already been using 3.0, but judging by the release notes there’s a lot of chewy Eclipse goodness loaded in this release. I’ve already downloaded it and “installed” it, such as it is. I’ve upgrading my JDK to 1.4.2 and will fire the new Eclipse up shortly.

Update: OK, I’ve got M2 and JDK 1.4.2 installed. While it does monopolize my CPU on startup, once up it is fast! And there are lots of spiffy new features. My favorites so far are the JavaDoc and Declaration views. The JavaDoc view shows the javadoc for the selected method and the declaration view shows the declaration. Clicking on the “println” part of System.out.println results in the javadoc or the source code being shown, depending on which view is selected. Another feature, which mimics something that is in the new IntelliJ is a change indicator in the gutter on lines that you’ve changed in this editing session. Hovering over the marker shows what the line looked like before and allows you to revert changes. Very nice, indeed!