Thursday, December 6, 2007

Using OpenJDK 1.6 (Java 6) with IntelliJ

I have been able to use the SoyLatte (a.k.a. version 1.0 of the Java 6 Port for Mac OS X 10.4 and 10.5) to compile my projects in IntelliJ. It was fairly painless. To do so:

  1. Install OpenJDK 1.0. Brandon recommends putting it in /usr/local/soylatte16-amd64, but I went ahead and put it in /System/Frameworks/JavaVM.Framework/Versions. Makes more sense to me that way, but it doesn't really matter.

  2. In IntelliJ open up your project preferences (Cmd-,)

  3. Click on "JDKs"

  4. Add a new one.

  5. Add the following jars to the classpath:
    ${install_dir}/soylatte16-i386-1.0/lib/dt.jar
    ${install_dir}/soylatte16-i386-1.0/lib/jconsole.jar
    ${install_dir}/soylatte16-i386-1.0/lib/tools.jar
    ${install_dir}/soylatte16-i386-1.0/jre/lib/charsets.jar
    ${install_dir}/soylatte16-i386-1.0/jre/lib/jce.jar
    ${install_dir}/soylatte16-i386-1.0/jre/lib/jsse.jar
    ${install_dir}/soylatte16-i386-1.0/jre/lib/management-agent.jar
    ${install_dir}/soylatte16-i386-1.0/jre/lib/resources.jar
    ${install_dir}/soylatte16-i386-1.0/jre/lib/rt.jar

And you're done. Note that this is only to compile existing projects with Java 6 using IntelliJ. If you want to launch IntelliJ with Java6 you're on your own.

Tuesday, November 20, 2007

IntelliJ: t3h awesome (mostly)

I installed IntelliJ a couple of weeks ago, and have thus far been impressed. After using Eclipse for the past three years I've been getting more and more annoyed at its sluggishness. I tried NetBeans for about three days, but quickly got frustrated with it. IntelliJ, however, is a lean, mean, fighting machine, intuitive in all the right places and a breeze to use, with a couple of exceptions.

My primary positive praise is all about the speed: IntelliJ is fast. After using the bloated beast that is Eclipse, using IntelliJ makes my neural receptors hum with delight. Loading up and switching between projects is faster. Setting preferences is faster. Tweaking the classpath, refactoring, searching for references, and generating code coverage reports: all faster.

And Groovy? Don't even get me started. The Groovy plug-in for Eclipse is like using a climbing Mt. Everest while drunk: technically possible, but something that will quite likely lead to an early death. The Groovy support in IntelliJ is robust and... fast.

Editing non-Java files is also a breeze. Now, normally I am a vim nut. For years I have been using vim for editing JSPs, XML, config files, etc. Basically, if it's not a Java class, I use vim. I have plenty of macros and various vim-crap to help me along, but IntelliJ is the first thing I have used that has caused me to use vim less -- much to my own surprise. The XML editor is tight: it reads your DTD/schema and lets you do the cmd-space trick for auto-completion of tag names and attributes. Spring configuration files are validated against known classes, so if you reference a bean that IntelliJ doesn't know about, it flags your config file with an error.

Nice.

But all is not roses. We have an extensive Struts application where I work, and the Tiles integration seems to simply be broken. For example, in the following example the input is flagged as an error even though that tile is defined elsewhere:

<action path="/searchPromos" input=".Mpr.Main">

Also, there were problems with the GWT integration that I was unable to overcome. This may simply be due to my inexperience with that framework, so I will not go into detail about that until I am more confident where the blame lays.

There are also two views that Eclipse has that IntelliJ does not: JavaDoc and declaration. I kept these open all the time in Eclipse, and I miss them. The IntelliJ way of viewing JavaDocs is to hit ^j. While this is fine, I still miss my dedicated view.

On the plus side, IntelliJ validates your JavaDocs more thoroughly than Eclipse does. For example, IntelliJ raises a flag in the following due to the discrepancy between what is documented (param) and what is coded (param1):

/**
* A method which does something
*
* @param param
*/
public void doSomething(int param1) { ... }


In any event, IntelliJ is an excellent IDE. It is different from Eclipse, to be sure, but they are kissing cousins. The initial effort I put into it has paid off nicely thus far, and switching has not cause me any undue pain.

Thursday, November 1, 2007

Quickstart: Drools 4.0.3 Web Admin (BRMS)

The documentation on Drools is a little bit light on the "where the hell do I start" part, so here's a quickstart guide. I'll walk you through getting the equivalent of a "Hello, World" app up in Drools, i.e. the simplest setup possible. This will use the Drools web management interface, and will not require any actual code whatsoever. This assumes that you, much like myself, in fact know next to nothing about Drools, and just want to play with it before getting into Rete algorithms and truth maintenance and all that crap.

Isn't that nice.

There are only three requirements.
  1. You have your own servlet container: Tomcat, Glassfish, whatever.

  2. You have in your possession a JavaBean in some .jar flie somewhere. Any bean will do.

  3. You don't require screenshots. Sorry, I'm lazy. Maybe in the future.

That's it.

  1. Download the Drools BRMS from JBoss.

  2. Deploy it to your app server. I like Glassfish.
    [0932][jchilders@Ivan:~/webapps]$ unzip drools-4.0.3-brms.zip
    [0932][jchilders@Ivan:~/webapps]$ sudo asadmin
    Use "exit" to exit and "help" for online help.
    asadmin> start-domain domain1
    asadmin> deploydir ./drools-brms/

    Log in to it. (Mine deployed to http://localhost:8080/drools-jbrms/). User ID is "", password is "", without the quotes.

  3. You should see five options on the left: Info, Rules, Packages, Deployment, and Admin. Click on Admin.

  4. Click on "Create New Category".

  5. Name your category something clever. We'll call ours "BannerAds". Save it.

  6. Click on "Packages". There is a button on this page that will allow you to create a new package. It is small and has no label, but does have a tooltip. Click on it.

  7. Give your package a name and optional description. We'll call ours "MyPackage". Save it.

  8. There is another tiny, hard-to-find button on this page that allows you to create a new model. Click on it.

  9. This model will reference the jar file that has your bean it in I mentioned earlier. Name it something witty like "MyBean" and save it.

  10. You should be at a screen that will let you upload your jar. Do it.

  11. Click on the "Save Changes" button.

  12. Holy crap we're almost there! Now click on the "MyPackage" package in the tree, then "Edit Package Configuration" in the main window.

  13. In the "Header" section in the main window you need to actually tell Drools about your bean. To do so:
    import com.mycompany.MyBean

    No semicolon at the end. If you want to get crazy and are lucky enough to own more than one JavaBean, do more than one import.

  14. Wow we should actually be able to make a rule now! AWESOME!

  15. Click on the massive 16px button that will let you "Create New Rule"

  16. Give it a name and category and type it as "Business rule". Save.

  17. Ok, now comes the real test. Click on the big green plus sign to the right of "WHEN". You should see a window that says "Add a condition to the rule..." If everything was set up correctly -- and that's a big if -- then you should see two selects: "Fact", and "Condition Type". If all it says is "Add a condition to the rule..." and nothing else, then you screwed up. Also these instructions may be wrong. It is much more likely that you screwed up because I have a blog. If it doesn't work please go to step RTFM, else continue.

  18. Fact. Click on it. Select your bean.

  19. Figure out the rest on your own. You're now to the point where you can create rules based upon your bean. Doing so using the visual editor is pretty self-explanatory.

May the force be with you, always.

Wednesday, October 31, 2007

Leopard, Java6, and immaturity

I have never before been ashamed to be a Java developer.

Apple did not include Java6 in last week's release of OS X Leopard. This came only a few short weeks after Apple pulled a Java6 beta that was available on ADC, with no word as to why. These two factors together seem to have triggered a firestorm in parts of the Java community, the most infamous being Michael Urban's disjointed rant over at JavaLobby where he fumes about the above issues at length, and eventually concludes that he's going to take his toys and go home, e.g. abandon OS X as his dev platform. The tone and content amount to nothing more than "I don't have what I want, when I want it, so SCREW YOU!" Judging from the comments he was hardly alone.

This is just embarrassing.

Leopard has been out for a grand total of five days. Five. Having such an extreme reaction to the lack of Java6 in the .0 version of Leopard is just...  wow. I really don't have words for it. Arrogant? Short-sighted? Immature? Completely ignorant of what it takes to get an operating system shipped? It certainly isn't supported by history.

Once Java 1.4 was added to OS X 10.0, Apple has always included Java in its operating system. Always. It is apparent that Java isn't a top priority for the company, but that does not mean that it has *zero* priority, or that those priorities are even skewed. Apple's primary target is and always has been the consumer market. Java simply isn't a player in that space. Further, Java powers much of apple.com -- including the iTunes Music Store -- so it is hardly in Apple's interest to neglect it.

None of the complaints change the fact Macs are still an extremely enjoyable environment to develop Java applications on, far better than Windows or Ubuntu. For me this is the important part: what tool do I feel most comfortable using? Java6 availability changes that not at all.

Even if Java6 were available its lack of penetration even within the Java-sphere would really make it more of a novelty than a must-have. Sad, possibly, but true.

----

Addendum: There are a few words that when I run across in an article cause me to immediately take what is being said less seriously. "Fanboy", "zealot", and their ilk are large red flags. The newest one is "Steve Jobs". From the previously linked to article: "But once again, the part I have really had it with, is the unprecedented arrogance of Steve Jobs and company..." Steve Jobs has had more unsupported adjectives thrown at him than I think anyone since Bill Clinton. For many Jobs has become a rhetorical foil, something used more for emotive effect than anything else.

Thursday, October 11, 2007

JCAPTCHA: Never mind. We hates it.

So after spending numerous hours last night trying to figure out how to create a custom CAPTCHA image using JCAPTCHA, I realized a few things
  1. The documentation is, to be kind, sparse. Also it's written by people whose first language is decidedly not English. That's fine if the code is so elegant as to be self-documenting, buuut....
  2. The API is difficult to grasp. It relies too heavily on inheritance; a few strategies and a Builder would help to clean things up immensely.
  3. If you decide against using one of the built-in image generators, then you must familiarize yourself with an undocumented collection of ImageFilters for which the source code is unavailable.
    TwirlFilter is a perfect example. Figuring out how to implement a TwirlFilter required becoming a monkey banging away on a keyboard: eventually and almost totally by random I got something that worked. Further, some of the methods inherited by TwirlFilter actually cause NPEs when called, and since there's no documentation there is no way to tell what does what or, in some cases, even what units are expected.
    For example, TwirlFilter.setAngle(int) takes radians as its argument, but there is no way to know this in advance.
This is just a workplace shooting waiting to happen.

For posterity's sake, here's how you would implement a TwirlFilter in JCAPTCHA:

  protected void buildInitialFactories() {
   
WordGenerator wg = new RandomWordGenerator(CHAR_LIST);

    FontGenerator fontGen =
new TwistedAndShearedRandomFontGenerator(new Integer(24), new Integer(30));
    BackgroundGenerator bgGen =
new UniColorBackgroundGenerator(new Integer(200), new Integer(100), Color.WHITE);
    TextPaster textPaster =
new RandomTextPaster(new Integer(5), new Integer(8), new RandomListColorGenerator(TEXT_COLORS));

    ImageFilter
[] noFilters = { };
   
    TwirlFilter twirlFilter =
new TwirlFilter();
    twirlFilter.setAngle
(1);    // In radians
   
   
ImageFilter[] textFilters = { twirlFilter };
    ImageDeformation bgDeformations =
new ImageDeformationByFilters(noFilters);
    ImageDeformation textDeformations =
new ImageDeformationByFilters(textFilters);
    ImageDeformation finalDeformations =
new ImageDeformationByFilters(noFilters);   

    WordToImage wordToImage =
new DeformedComposedWordToImage(fontGen,
        bgGen,
        textPaster,
        bgDeformations,
        textDeformations,
        finalDeformations
);

    addFactory
(new ShearedWhiteBackgroundGimpyFactory(wg, wordToImage));
 
}