Tag: eclipse

 

Solr's Lucene Source

I’m debugging a plugin for Solr. I’ve just about got the magic voodoo set up so that I can make Eclipse talk to tomcat and stick breakpoints in and so on. But I’ve immediately run into a problem.

Even though Solr itself comes with -sources jars, the bundled copy of lucene that they’ve used doesn’t. Needless to say, this is a bit of a hindrance.

Thankfully, the apache people have set up git.apache.org, which makes this situation a lot less annoying than it could be.

First, I checked out copies of lucene & solr.

$ git clone git://git.apache.org/solr.git
$ git clone git://git.apache.org/lucene.git

Now, I need to go into solr and figure out which version of lucene is in use. Unfortunately, it’s not a released version, it’s a snapshot of the lucene trunk at a point in time.

$ cd/solr
$ git branch -r
  origin/HEAD -> origin/trunk
  origin/branch-1.1
  origin/branch-1.2
  origin/branch-1.3
  origin/sandbox
  origin/solr-ruby-refactoring
  origin/tags/release-1.1.0
  origin/tags/release-1.2.0
  origin/tags/release-1.3.0
  origin/trunk
$ git whatchanged origin/tags/release-1.3.0 lib
…
commit 904e378b7b4fd18232f657c9daf484a3e63b272c
Author: Yonik Seeley <yonik@apache.org>
Date:   Wed Sep 3 20:31:42 2008 +0000
 
    lucene update 2.4-dev r691741
 
    git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/branches/branch-1.3@691758 13f79535-47bb-0310-9956-ffa450edef68
 
:100644 100644 a297b74... 54442dc... M  lib/lucene-analyzers-2.4-dev.jar
:100644 100644 596625b... 5c6e003... M  lib/lucene-core-2.4-dev.jar
:100644 100644 db13718... f0f93a7... M  lib/lucene-highlighter-2.4-dev.jar
:100644 100644 50c8cb4... a599f43... M  lib/lucene-memory-2.4-dev.jar
:100644 100644 aef3fb8... 79feaef... M  lib/lucene-queries-2.4-dev.jar
:100644 100644 1c733b9... 440fa4e... M  lib/lucene-snowball-2.4-dev.jar
:100644 100644 0195fa2... b5ff08b... M  lib/lucene-spellchecker-2.4-dev.jar
…

So, the last change to lucene was taking a copy of r691741 of lucene’s trunk. So, lets go over there. And see what that looks like.

$ cd/lucene
$ git log --grep=691741

Except that doesn’t return anything. Because there was no lucene commit at that revision in the original repository (it was something to do with geronimo). So we need to search backwards for the commit nearest to that revision. Thankfully, git svn includes the original subversion revision numbers of each commit.

$ cd/lucene
$ git log | perl -lne 'if (m/git-svn-id:.*@(\d+)/ && $1 <= 691741){print $1; exit}'
691694

So now we can go back and find the git commit id that corresponds.

$ cd/lucene
$ git log --grep=691694
commit 71afff2cebd022fe63bdf2ec4b87aaa0cee41dc8
Author: Michael McCandless <mikemccand@apache.org>
Date:   Wed Sep 3 17:34:29 2008 +0000
 
    LUCENE-1374: fix test case to close reader/writer in try/finally; add assert b!=null in RAMOutputStream.writeBytes (matches FSIndexOutput which hits NPE)
 
    git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@691694 13f79535-47bb-0310-9956-ffa450edef68

Hurrah! Now I can checkout the same version of Lucene that’s in Solr. But, probably more useful for Eclipse, is just to zip it up somewhere.

$ cd/lucene
$ git archive --format=zip 71afff2 >/tmp/lucene-2.4-r691741.zip

Excellent. Now I can resume my debugging session. 🙂

NB: I could have just used subversion to check out the correct revision of Lucene. But, I find it quicker to use git to clone the repository, and I get the added benefit that I now have the whole lucene history available. So I can quickly see why something was changed.

Using a Java 6 based Eclipse with Cocoa

This is somewhat niche, but I’m going to post it anyway in case it helps somebody else

I recently saw a problem with Eclipse and m2eclipse. When I tried to import a Java 6 based project, I got an error in the maven console.

Failure executing javac, but could not parse the error:
javac: invalid target release: 1.6
Usage: javac  
where possible options include:
 -g                         Generate all debugging info
 -g:none                    Generate no debugging info
 -g:{lines,vars,source}     Generate only some debugging info
 -nowarn                    Generate no warnings
 -verbose                   Output messages about what the compiler is doing

This is happening because m2eclipse is trying to run the compiler from within the same JVM that Eclipse is running. And by the eclipse.org downloads only offer Carbon and Cocoa options. Both of these are 32 bit. Which means they’ll only ever run using Java 5, even if you’ve got Java 6 installed (unlike my iMac G5, grumble, grumble).

Thankfully, the 64 cocoa version is available, though it’s only the old “Eclipse SDK” download. But ekke wrote up [galileo] EPP for Cocoa 64-bit, which shows how to go about getting (effectively) the same setup as the eclipse.org downloads.

If you follow along that procedure, you get an eclipse that works well with m2eclipse and Java 6 project. As a bonus, it feels quicker to me.

Hopefully future versions of Eclipse will offer a 64-bit cocoa download.

Responsiveness

Yesterday, whilst trying out Eclipse 3.5, I noticed a problem with the new XSLT support. So, I filed bug 279793 (All XSLT 2.0 has validation errors in xslt-2.0.xsd).

I got a response in under 30 minutes, including a workaround and an integration into the next release. That is completely awesome!

I’d like to say a huge thanks to Dave Carver for his work, not just on fixing this bug, but also on getting the XSLT integration with Eclipse. That was something I’d been missing for a while.

Eclipse 3.5 in Cocoa

I’m just trying out Eclipse 3.5-RC4. One of the big new features for me is that it’s now based on Cocoa instead of Carbon. There are many benefits to this, including being able to run on 64-bit Java 6. Fundamentally, it just looks and feels a little bit more mac-like.

As an example, one nice little mac feature I use a bit is “lookup this word in the dictionary”. If you hit Ctrl-Cmd-D and hover over a word, you get an in-place definition. Eclipse now does this:

Looking up a word in the dictionary inside Eclipse

It doesn’t work everywhere (which you can probably guess from the context of that screenshot), but it is an indicator that Eclipse & mac are coming together. This is great news for Java developers on the mac.

Oh, it does feel a little bit faster too, which can’t hurt.

More Java Memory Analysis

If you found Heap Dump Analysis interesting, you might also be interested in Identifying ThreadLocal Memory Leaks in JavaEE Web Apps from Igo Molnar. I saw this a day or so after my original post. He uses The eclipse memory analysis tool (MAT) to figure out what’s going on.

In his case, he couldn’t use visualvm as the heap dump was too large.

I downloaded MAT for my problem and had a look at it. It seems like it does much more than visualvm (there are may “pre-canned” queries available, plus an “object query language”). But that makes it correspondingly harder to use. I spent a while going through the tutorials to get the hang of it, whereas visualvm seemed to come together quickly for me. I suspect that if I ploughed more time into it, I’d get a lot more out of it. It seems to be something that I should learn before I get to need it again. 🙂

Eclipse Update Failure

I’ve just hit the “update everything” button in my Eclipse install. All seemed well until I restarted it and got a message about a shared library not being found. Looking in Console.app showed this lovely little line:

09/02/2009 14:33:07 [0x0-0x1ef1ef].org.eclipse.eclipse[43353] dlopen(../../../plugins/org.eclipse.equinox.launcher.carbon.macosx_1.0.100.v20080509-1800, 2): image not found

Fairy ’nuff. I had a quick grep in the eclipse folder and found that it’s referenced by eclipse.ini (in Eclipse.app/Contents/MacOS). Using the magic of vim’s filename completion (^X^F) I corrected it to the newly updated version:

--- eclipse.ini.orig	2009-02-09 14:39:16.000000000 +0000
+++ eclipse.ini	2009-02-09 14:39:19.000000000 +0000
@@ -1,5 +1,5 @@
 --launcher.library
-../../../plugins/org.eclipse.equinox.launcher.carbon.macosx_1.0.100.v20080509-1800
+../../../plugins/org.eclipse.equinox.launcher.carbon.macosx_1.0.101.R34x_v20080731
 -startup
 ../../../plugins/org.eclipse.equinox.launcher_1.0.101.R34x_v20080819.jar
 -showsplash

Now, eclipse starts again.

NetBeans 6.5

Today NetBeans 6.5 got released. Congratulations, guys! I’m primarily an Eclipse user1, but I keep hearing about NetBeans through the Java Posse and heck, I even subscribe to the NetBeans podcast to try and keep an eye on what’s up. Every time a new release comes out, I give it a whirl.

So this time, now I’m looking at 6.5. And it’s really nice on a lot of fronts. Most of the improvements in 6.5 aren’t directly relevant to me — they’re related to scripting languages I don’t use. What I’m particularly interested in is the core Java SE support. And NetBeans is really very good. It’s just not quite as good as Eclipse. Or (more likely) I can’t figure out a way to make it do what I want.

There are a couple of things I do all the time in Eclipse. First, ⌘-T, which shows type hierarchies. But that’s putting it simply. If you pop it over a class, it shows the subtype hierarchy. Press it again and it shows the supertype hierarchy. What’s neat is that if you do it over a method, it greys out those classes that don’t have an implementation of that method.

⌘-T in Eclipse

But what makes it particularly useful is that it doesn’t pop up a proper window, just a little floater (I have no idea what it’s really meant to be called). As soon as you click somewhere, it disappears. This makes it incredibly fast to navigate code.

As far as I can see, the closest that NetBeans has is “File Hierarchy” on ^⇧F12. But this pops up a big old clunky dialog box.

That’s one more thing about NetBeans — the key bindings are weird. And I speak as a long time emacs user. Now I’ll learn them (as it’s annoying to carry my customisations everywhere). But they conflict badly with a lot of Mac keyboards, because they’re extremely function-key heavy, and the mac likes to take over the function keys for itself.

The other Eclipse feature I use the whole damn time is “assign to local variable”. Yes, you can curse me for being damned lazy. But, I want to be able to type new PhoneImpl("01273", "123456"); then hit a key and get it assigned to a variable. In Eclipse, that’s ⌘-T L. I couldn’t find a way to do it in NetBeans. The compiler knows what type it’s going to be. Why should I have to remember? Otherwise I’d be back in Emacs.

There are a couple of missing refactorings I use a lot: “Extract to local variable” and “inline local variable”. Both are easily replaced with cut’n’paste 90% of the time.

One particular feature that Eclipse and NetBeans both share is terrible defaults for exceptions. Here’s Eclipse’s default:

  try {
      new URI("http://example.com/");
  } catch (URISyntaxException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
  }

And here’s NetBeans.

  try {
      new URI("http://example.com/");
  } catch (URISyntaxException ex) {
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
  }

Both of these are fundamentally broken, and going to catch out dozens of unwitting programmers who don’t know any better. Yes, you can change the defaults, but most people don’t.

Anyway I don’t want you to think that I’m totally down on NetBeans. The new release maintains what I first saw in 6.1: a very fast, full featured IDE. It’s dead easy to get going, and there is loads of documentation. I find the project view to be much more useful and better organised than the eclipse view of the same.

NetBeans Project View

I suspect that most of the problems I’ve been having are down to the fact I’ve been using Eclipse for 3 years, and NetBeans for a few hours at best.

One thing I did like very much is that there’s builtin Maven support. I downloaded the Java SE installation2, went to the plugins window and selected “maven”. About a minute later I had a working installation. And I can create new projects with archetypes really simply. And it’s dead simple to add new libraries as needed (I’m guessing it uses the nexus indexer to look stuff up). The only missing thing is the dependency viewer, but I can always run dependency:tree and dependency:analyze manually.

Funnily enough, where I think NetBeans really wins is the dynamic languages support. I’ve been following Tor’s blog for a little while and I’m incredibly impressed with what has been achieved in the Ruby support. For developing Ruby code, I head straight for NetBeans. Most of the issues I’ve outlined above are really specific to statically typed languages. For dynamic languages like Ruby (and now PHP and Python), what NetBeans gives you is a big win over the standard text editor.

Heck, the JavaScript support is pretty decent too. The first thing I did today was open up jslint4java and jump into fulljslint.java. That’s some pretty scary code. But NetBeans handled it with no issues at all. And it even pointed out a warning that’s easy to overlook (a duplicate hash key).

So, the big question is — am I going to use NetBeans? For any Ruby stuff, there’s no question. For Java stuff, I’m going to give it a try. After spending enough time with it to write this, I’ve already figured out enough stuff to use it a bit more successfully.

1 Apart from Emacs, Vim and TextMate. ☺

2 I didn’t like the look of the Java EE version — I don’t really need 3 application servers bundled, do I?

Exceptional Origins

I’ve just noticed something rather nice in Eclipse. The “Mark Occurrences” feature (Mark Occurrences) will show you where an exception is thrown. For example, here I’ve clicked on the IOEXception in the method definition.

Eclipse highlights where exceptions are thrown

You can clearly see that read(), write(), flush() and close() are points at which the IOEXception can be thrown.

Similarly, you can highlight the return type of a method to see all the exit points of a method.

Eclipse highlights all return sites in a method

One final tip about Mark Occurrences: You can optionally select occurrences in the “Next / Previous” toolbar buttons. i.e.

Enabling “next occurrence” in eclipse

Doing this allows the Next key (Command-. on my Mac, likely Ctrl-. on Windows) to jump between occurrences. So you can click on a method name and cycle through all mentions of that method in a file. Very handy. You’ll notice that it works for compile errors too.

I have to confess that I used to find Mark Occurrences quite irritating. Now I know what it can do for me, I’m a much happier punter.

Exceptional Eclipse Tip

By default, when eclipse creates a try/catch block for you, you end up with something like this:

  try {
    doSomething();
  catch (EvilException e) {
    // TODO auto-generated catch block.
    e.printStackTrace();
  }

This is worse than useless, as it (effectively) covers up the exception1. A far better default choice is to wrap the checked exception in a RuntimeException if you don’t know what to do with it.

Thankfully, it’s fairly easy to arrange this in eclipse. Go to Preferences → Java → Code Style → Code Templates and edit the “catch block body” fragment. It should look like this:

eclipse-catch-block-template.png

I’m going to try and spread this around the office a bit. It should make for some slightly more robust code…

1 Please don’t remind me that it comes out on the console—people are very good at ignoring that.

Tomcat Logging in WTP

I’ve just been trying to enable debug logging for tomcat (don’t ask). Normally you do this by editing $CATALINA_HOME/conf/logging.properties and restarting.

Except I tried that in Eclipse (using WTP) and it didn’t work.

I tried copying it to the $CATALINA_BASE/conf directory instead1.

Still no joy.

I’ve just found the answer, after looking in the tomcat source. It turns out that tomcat’s alternative logging implementation (JULI) is enabled via a system property. This happens inside catalina.sh:

# Set juli LogManager if it is present
if [ -r "$CATALINA_BASE"/conf/logging.properties ]; then
  JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
  LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
fi

But Eclipse runs the Java code directly, without using catalina.sh. So the properties never gets set. You have to set them by hand in the “Run Configurations” dialog. Like this:

Setting system properties for tomcat in Eclipse

Of note there is that I’ve imported the logging.properties file into the Servers project of my workspace. It seemed liked a useful place to put it.

Of course, after realising that, I soon find the same information in the WTP FAQ: How do I enable the JULI logging in a Tomcat 5.5 Server instance?.

Anyway, now I might be able to debug that ClassLoader issue…

1 Inside Eclipse with WTP, that will be something like $WORKSPACE/.metadata/.plugins/org.eclipse.wst.server.core/tmp0.