Arsenalist

Arsenal blog by a Canadian

Archive for the 'java' Category

Logging abstraction is utterly pointless

Posted by Arsenalist on 12th September 2007

I had always thought so but in the last week I’ve concluded with dynamite determination that logging abstraction is completely pointless. No. Benefit. Whatsoever. Could I be mistaken? No, if anything you’re probably still hanging on to Commons Logging because somebody told you how great it was, I don’t think anyone in their right mind would, after taking a step back and looking at the circumstances say, Hmmm, I really need to be careful and not commit myself to Log4J because God knows when Mark Womack and his team might pack it in and leave me hangin’. The same people who name their first born after Commons Logging classes commit themselves to products like IText, JFreeChart and GodKnowsWhat without ever thinking about abstraction. Raise your hand if you’re ever used IText and considered what happens if you want to switch your PDF generation tool? Nobody? So why the hell do we care so much about logging?

Luckily the answer is as simple as it is stupid: making a logging tool is so freaking easy that everybody’s got a homegrown one which they swear by and would never ditch even if they were offered ass in return (this just in, Logger just won the most used classname ever, it beat out Tester). So instead they use Commons Logging which gives them the feeling of not being such a big idiot with the added bonus of sleeping well at night knowing that they could eaaaasily switch to Log4J if they wanted to. What these poor saps don’t know is that switching between logging tools isn’t even that easy regardless of the abstraction, you still have to worry about configuring your tool which is a major pain in the ass if you want to actually stick to the proper log levels. Besides, nobody’s switching to anything, once you pick a logging framework you stick with it until the application is dead. Period. No exceptions. And if you happen to be switching your logging implementation so frequently that you need abstraction you suck at design and product evaluation.

Do you really care which of the two following imports you’d rather have shit on your code: org.apache.commons.logging or org.apache.log4j. Unless you have a thing for using commons packages (and some people do) you probably don’t give a rats ass. So with that in mind why don’t we save ourselves some trouble and just use Log4J, and as a bonus I’ll throw in the pro of Tomcat not barfing every time it sees two commons logging jars in its classpath, God forbid if they’re two different versions because then it starts giving you errors that make you regret ever even getting into Java.

The only way to beat Log4J is to have something out of the ever so trustworthy java.* packages do the logging for you. Luckily there’s JULI which is really great but unfortunately it’s documented about as poorly as Guice and isn’t marketed nearly as aggressively as that retard Duke (I really hate that son of a bitch, looks like a tooth with a big cavity). Besides, anytime anyone asks you to modify something in the JAVA_HOME directory to configure something red flags go up. Somebody please document how to load a config file from your classpath without specifying a -D option in JAVA_OPTS. I mean I’m configuring logging, not optimizing my garbage collection, yeeeesh.

Subscribe to Arsenalist's tech feed

This post has moved to here.

Posted in Technology, java, log4j, tech | Comments Off

Career not going anywhere? Just change your title

Posted by Arsenalist on 21st August 2007

So you’ve been working away at your development job for God knows how long and there’s no end in sight to your misery. There’s no chance of moving up in the company and although your bosses like you, they don’t think much of you. They’re happy with what you’re doing as long as you do it quietly, deliver in the whereabouts of your deadlines, show up to the company picnic and stay out of any real decision making. You’re taking up more and more responsibilities over the years but your pay is only being raised by a paltry 2% while the cost of living is going up by 5. You know you’re being fucked but are too lazy or incapable of doing anything. So what do you do? You change your title of course.

Read the rest of this entry »

Posted in Technology, java, tech | 9 Comments »

CXF WS-Security using JSR 181 + Interceptor Annotations (XFire Migration)

Posted by Arsenalist on 31st July 2007

This post has moved here.

Posted in cxf, java, maven, spring, tech, web services, xfire | Comments Off

Unit Testing Struts 2 Actions wired with Spring using JUnit

Posted by Arsenalist on 18th June 2007

This post has moved here.

Posted in java, junit, spring, struts, tech, testing | Comments Off

When Web 2.0 goes wrong – Part 2

Posted by Arsenalist on 6th June 2007

Here’s the second part of my rundown of Webware’s “best web apps“. Check out the first installment if you haven’t already. Here are the offenders:

Windows Live Hotmail: In other words, Hotmail. All the power to the guy who invented Hotmail and blew open the doors to internet communication, its just too bad Microsoft has since ruined Hotmail by first a) not improving it for the first five years after acquiring it and b) by handing the renovation project over to a bunch of monkeys who insist on making it look more like Windows, only slower. Just like anything else webby, Microsoft was late in pumping out a proper email platform and when it finally did, it forgot to copy Gmail properly. Instead it took the approach of copying Gmail and at the same time keeping components of the already crappy Hotmail intact. Bad move. I don’t want to right click to select multiple messages, we do that with checkboxes on the web. The Spam filtering is still brutal and the emails that you actually want to receive end up in the Junk folder (something that has NEVER happened to me with Gmail) or you’re forced to click pointless buttons like “Show Content” and “Mark as Safe” even for emails sent by your Mom. The interface shifts more often than Alberto Gonzales and 20% of the screen is taken up by an ad.  The concept of tags still hasn’t caught on and you’re forced into segregating content into folders.  If you have any integrity you should stop using Hotmail.

Windows Live Messenger: In other words, MSN. I still have a copy of 4.1 on my machine, see that’s where the product stopped being chatting software and turned into a slow and bloated commercial about other Microsoft services. Throw in links to date.com, some trashy horoscope sites, an MSN Today popup that should never have seen the light of day and you end up with Windows Live Messenger – the crappiest chatting software in the world. It must’ve been a slow year for Webware to select this piece of trash in their top 500. The problem with this thing is that it doesn’t know who its catering to so it tries to please everyone: huge emoticons, whiteboards, limits on how much an be typed, multiple contact groups, bulky user interface, games, celebrity gossip, all send mixes messages to someone who’s just trying to tell his wife to pick up some bread when coming back from work. Death to Messenger.

Flickr: OK, you have to understand that unless you have a pro account Flickr is about as useless as an appendix. Here are some of the restrictions: only three albums allowed, 100MB upload per month and here’s the kicker: You can only display 200 images at any given point! The last restriction pretty much encapsulates the first two rendering the entire product worthless for anyone who takes say 10 pictures a month. So much for the “Flickr loves you” slogan, a more appropriate one would be “Buy the pro account!”. Sure there’s some nice stuff, RSS feeds and of the sort but if you’re going to spend your money, don’t give it to Yahoo, they’re rich enough. Try SmugMug which is vastly superior and run by people who genuinely care about your user experience (use vz6dRtcdUp91g as the coupon code to help a brother out). If you’re too cheap to spend money on photography storage, PhotoBucket is still better than Flickr. They don’t have a great uploader but thanks to the people at Flock, that’s been taken care of.

MyPunchBowl: Again with the modal boxes. Go there, sign up, and try to add an event, then tell me what you think of the site. The love affair with Lightbox continues as it seems every alternate form is using it regardless of whether the usage is justified. Maybe its something about the screen dimming after you click on a button that gets developers and marketing folks all wet in the pants, either way it’s getting to the point where usability is being sacrificed for the sake of using a gimmick. Also, since when did it become so cumbersome to click “Edit” and then start typing that people have resorted to making multiple text boxes and textareas disabled only to bring them to life after an unintuitive click, thereby wasting away any sort of tacit knowledge the user might’ve had. Where and when did this design principle pop out? A site that is dead simple in the functionality it offers is made to look like a 70 year old whore in 5 inch heels.

Wink: This sight is a little scary. It’s a people search that searches social networks such as MySpace, Bebo, LinkedIn and Friendster to suck any information about the unfortunate soul whose name was typed. Apparently the privacy agreements you sign on some of these sites allow third party apps to search their databases, pull up personal info including photographs and display it to ANYONE, something that might not be apparent at first glance. Remember the times when it was cool to use an image for a button? Well that practice is still acceptable as long as the result is somewhat pleasing to the eye. Don’t tell that to the designers at Wink, they love to use buttons with gradients that bring you all the way back to 1998 making you wonder where the colored scrollbars which would make the experience complete are. The app doesn’t search Facebook so its pretty much pointless.

Posted in flickr, hotmail, java, msn, mypunchbowl, tech, wink | 10 Comments »

When Web 2.0 goes wrong – Part 1

Posted by Arsenalist on 5th June 2007

I was checking Webware’s finalists for something called the “best web apps” of the year and the first thing you notice is that almost every site on there is named like a pet that you might’ve once owned which later turned into roadkill. Some of the gems to be found include Zillow, Zoho, Bebeo, Meetro, Yoono, Ning, Geni, and the list continues. Curiosity got the better of me and I started on a journey of trying out some of the “best web apps” and trying to figure out how they can help me make my life complete or at least give me a better way to waste my time. So here’s what I thought of them:

MyBlogLog: This is what you call a regurgitated idea that’s been wrapped around an interface so ugly that it makes MySpace look like modern art. Here’s how it works: they beg you to link a JavaScript file in your code and then proceed to collect stats off of it, something Web Side Story did from the beginning of time and something which is replicated by AWStats to near perfection. If you’ve got a WordPress blog or anything other than Blogger, don’t bother with this crap. Oh yeah, as soon as you sign up some guy named “Eric” automatically becomes your “friend” and introduces himself as one of the owners of this operation. Funnily enough, judging by his last login date, he himself hasn’t logged in to this misadventure in over four days. But I encourage everyone to sign up and look at the “Edit Profile” page and tell me if you’ve ever seen a form so ugly and hideous.

Tangler: It doesn’t even matter what this site does. Its blatant rape of Ajax is so apparent that you just want to disable JavaScript for kicks and see how it reacts. Here’s a sign of bad design: you clicked on a main menu option and a “loading..” sign pops up while it fetches a static submenu. WTF? The site is generally agonizingly slow and I don’t really know who to blame for it, maybe its their adoption of the Yahoo API instead of Google Analytics thats pushing it down the toilet in terms of speed. The idea of the site (not a bad one) is to have all your discussions in one place, the execution however lacks the simplicity required, no, demanded by such a venture.

Venyo: This site lets you build and ruin reputations and calls itself the “web 2.0 trust provider”. You’re supposed to build a “trust index” until people stop thinking you’re a pedophile and finally allow you to comment on their blogs. People on this site have their trust settings such that you can see their first name, their last name, a close-up picture but NOT their username. This is how they justify their existence: “The lack of trust has always been an issue on the Internet and it will not get better with the emergence of new collaborative services particular to Web 2.0.” Building trust on this site means jack squat, hire 100 people in India, pay them a dollar each and you can run for president.

Squidoo: What do you call a blog without calling it a blog? A lens. As you strive and suffer your way towards becoming a “Lensmaster” you’ll realize that if you have to wait five seconds for a piece of content to load through Ajax and stare at the words “drumroll please” for the entire duration, it’s probably wiser to just load a new page. Much less aggravating. The site is trying to persuade its audience that its something different, cool and better, but in the end you’ll find out that is nothing but a slow, badly designed and introverted blogging software that wishes it was a wiki.

Platial: Another site which misuses Lightbox. By now I’ve lost count and am beginning to second guess a personal decision to allow Lightbox in an app that I’m currently working on. Make a map of your life! Doesn’t that sound exciting? For most of the blokes that means to work and back but Platial.com is counting on the world traveler amongst us to make it a success. But there’s only so much you can do when you’re relying entirely on Google Maps to do all the work for you; this idea sounds great in theory but practically speaking, it doesn’t work. The process of “adding places” to your map is not intuitive and the Ajaxy features such as searching for places isn’t thought out. Note to Platial: Only popup modal boxes when the user somewhat expects them! Wayfaring.com is much better but it doesn’t matter because Google just pwn3d both with MyMaps.

Yelp: Here’s an idea that isn’t half bad: Bitch about all the bad food you’ve ever eaten. How eager was I when I hit the Sign Up button only to have the door slammed in my face as my Canadian postal code was rejected. Maybe another time, another place.

Here’s Part 2.

Posted in java, mybloglog, platial, reviews, squidoo, tangler, tech, venyo, yelp | 10 Comments »

Struts 2 Validation using Annotations

Posted by Arsenalist on 10th May 2007

This post has moved here.

Posted in java, struts, tech | Comments Off

Reason #256794 why IE sucks: Ajax Caching

Posted by Arsenalist on 2nd May 2007

[digg=http://digg.com/programming/Internet_Explorer_s_love_for_caching_Ajax_calls]

This installment of Why IE Sucks? is dedicated to the innocent and virtuous developer who has spent hours and hours wondering why their Ajax calls are returning data so stale that it’s inedible to the point of being deadly. Here’s the scene: if you’re using Prototype or Scriptaculous and are wondering why Ajax.Updater or Ajax.Request are “not working” and the server-side call is never being made, relax there’s nothing wrong with what you’re doing, it all has to do with IE’s sick love of caching.

Firefox and any other browser made by developers possessing an IQ of over 50 don’t have this this “feature” as IE likes to call it. The easiest way to avoid this is to not make GET calls at all using Ajax.Request or Ajax.Updater, instead use POST and you’ll be fine. If you’re hell bent on using GET, you will have to make every call made to the server unique. The fastest and easiest way of doing this for me is to append a random number at the end of the query string. In other words, use the parameters option from Ajax.Options and throw in a random number as one of the request parameters:
[sourcecode language='jscript']
new Ajax.Request( ‘myPage.html’, {
method: ‘get’,
parameters: {
differentiator: Math.floor(Math.random()*50000)
}
});
[/sourcecode]
As nasty and laughable as the above code is, it works since your final URL will always be something like mypath.html?differentiator=25632 courtesy of the random number being generated. Again, all this can be avoided by just using ‘post’.

So why does IE go out of its way to break our balls? It’s the philosophy of assuming your customers have the exact same needs as the developer who made the piece of software. You’d think after making life miserable enough by not having a debugger for JavaScript, they’d go easy on us when it comes to the most basic things of web development but no, every sweat or tear extracted is a penny earned for Microsoft.

This post has moved here.

Posted in ajax, java, prototype, tech | Comments Off

Writing PHP clients for XFire, Axis and .NET Web Services

Posted by Arsenalist on 19th January 2007

If you’re finding yourself hunting down incomplete documentation about writing a PHP client for your Java or .NET web services, you’re not alone. PHP SOAP toolkits like NuSOAP and Pear SOAP provide sub-par API’s into web service development and give a decent person a really hard time when it comes to writing clients. The best way to go IMHO is using PHP’s built-in SOAP libraries. The other thing to keep your eye on is Axis2 for PHP which is still in Beta. For now we’ll focus on the PHP 5 and it’s SOAP extension. To enable the extension, your php.ini file must something like the following:

Under Dynamic Extensions:

extension_dir="C:/php/ext/"
extension=php_soap.dll

Under Module Settings:

[soap]
soap.wsdl_cache_enabled=0
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400

Restart the Apache Web Server for the changes to take effect, once that is done, we are free to use the PHP Soap extensions. This example is applicable to Java web services generated by XFire or Axis or any other framework and also to .NET web services. As long as there’s a WSDL, we’re good. This example has been tested with XFire 1.2.4.

In this example there is one web service called SportsService which exposes one method: public Mascot getMascot(Team team)

The method takes in as parameter a complex Java object called Team and returns a Mascot, another complex data type. Although this example can easily use primitives, I’ve chosen to use Java objects because I want to illustrate a specific point. The XFire Java client is fairly easy to write and a previous blog entry covered a similar client. Both the Team and Mascot classes are POJO’s with one String property called name, a default constructor and getter/setter methods. They are excluded here for brevity.

Before we look at the PHP client, let’s look at the relevant portion of the WSDL that is generated, mainly the types and the information about the method getMascot which we will be calling:

<wsdl:types>
    <xsd:schema
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            attributeFormDefault="qualified"
            elementFormDefault="qualified"
            targetNamespace="http://vo.arsenalist.com">
        <xsd:complexType name="Team">
            <xsd:sequence>
                <xsd:element minOccurs="0"
                             name="name"
                             nillable="true"
                             type="xsd:string"/>
            </xsd:sequence>
        </xsd:complexType>
        <xsd:complexType name="Mascot">
            <xsd:sequence>
                <xsd:element minOccurs="0"
                             name="name"
                             nillable="true"
                             type="xsd:string"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:schema>
    <xsd:schema
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            attributeFormDefault="qualified"
            elementFormDefault="qualified"
            targetNamespace="http://ws.arsenalist.com">
        <xsd:element name="getMascot">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element maxOccurs="1"
                                 minOccurs="1"
                                 name="team"
                                 nillable="true"
                                 type="ns1:Team"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
        <xsd:element name="getMascotResponse">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element maxOccurs="1"
                                 minOccurs="1"
                                 name="out"
                                 nillable="true"
                                 type="ns1:Mascot"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>
</wsdl:types>

Here’s the PHP client that creates a Team type, passes it to the web service which returns a Mascot type.

<?php

//set up the service client using WSDL
$wsdl = "http://arsenalist.com/SportsService?wsdl";
$client = new SoapClient($wsdl);

// assign the name attribute of Team to "toronto"
$wrapper->team->name =
		new SoapVar("toronto", XSD_STRING);

// call the getMascot method
$response = $client->__soapCall("getMascot",
				    array($wrapper));

// print out the Mascot
print($response->out->name);

?>

The wrapper object is created out of the blue so as to pass it to the web service as the lone parameter encapsulating the Team data type.

By looking at the WSDL, we can determine how to “instantiate” Team and Mascot data types on the client side. For example, to create a Team data type and assign it’s name property to “toronto”, we simply refer to it using associative array syntax and both the Team object and it’s property name are created “on the fly”. There’s no mucking around with namespaces etc. We’re simply wrapping the primitives inside other PHP “objects” using the same syntax as associative arrays. You can go as deep as you want in the object hierarchy in PHP without having to worry about encountering nulls because if an array element being accessed doesn’t exist, it is created for you.

It’s also always a good idea to use the $client->__getTypes() and do a print_r(..) on the results to see what you are dealing with before you start communicating with a WSDL For example, the result of a print_r($client->__getTypes()) on the above WSDL returned the following:

Array (
   [0] => struct Team { string name; }
   [1] => struct Mascot { string name; }
   [2] => struct getMascot { Team team; }
   [3] => struct getMascotResponse { Mascot out; }
)

As you can see this information can be helpful when deciding how to initialize your client side variables.

Note that you can also use $client->getMascot($wrapper) instead of $client->__soapCall(“getMascot”, array($wrapper)). The latter is used mostly when passing extra parameters such as SOAP headers etc.

This is a fairly simple example which hopefully illustrated the point that accessing web services using PHP is not a daunting task, and most of all there are no additional libraries to install as long as you’re using PHP5 and up.  If you would like write a PHP client that accesses a WS-Security enabled service, you should read Kim Cameron’s IdentityBlog entry which has links to the source code needed.

Posted in java, php, web, web services | 9 Comments »

JAXB2: XML to Java and vice-versa made easy

Posted by Arsenalist on 22nd December 2006

This example has moved.

Remember the old days when you used to write a 150 line method which parsed your XML file into a Java class? Well that has long since been history. The next generation version of the JAXB XML processor, appropriately named JAXB2 has taken the liberty to make XML to Java conversion straightforward. Converting Java objects to XML has also been reduced to something trivial. Given an XSD, JAXB2′s XJC tool generates Java classes corresponding to your XSD Schema. Once you have the Java classes generated, reading and writing XML is a breeze.

The ONJava article by Deepak Vohra talks about this conversion process with JAXB. JAXB2 makes the process even easier as it generates fewer Java classes making the API calls even more intuitive. Marshalling and unmarshalling Java objects becomes dead simple.

The JAXB2 RI comes bundled with the Java Web Services Developers Pack 2.0

Given the following XSD, running the XJC command generates four Java files.

<xsd:schema
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <xsd:element name="catalog" type="catalogType"/>
 <xsd:complexType name="catalogType">
  <xsd:sequence>
   <xsd:element ref="journal"  minOccurs="0"
		maxOccurs="unbounded"/>
  </xsd:sequence>
  <xsd:attribute name="section" type="xsd:string"/>
  <xsd:attribute name="publisher" type="xsd:string"/>
 </xsd:complexType>
 <xsd:element name="journal" type="journalType"/>
 <xsd:complexType name="journalType">
  <xsd:sequence>
   <xsd:element ref="article"  minOccurs="0"
                       maxOccurs="unbounded"/>
  </xsd:sequence>
 </xsd:complexType>
 <xsd:element name="article" type="articleType"/>
 <xsd:complexType name="articleType">
  <xsd:sequence>
   <xsd:element name="title" type="xsd:string"/>
   <xsd:element name="author" type="xsd:string"/>
  </xsd:sequence>
  <xsd:attribute name="level" type="xsd:string"/>
  <xsd:attribute name="date" type="xsd:string"/>
 </xsd:complexType>
</xsd:schema>

c:\Sunjwsdp-2.0jaxbbinxjc -p my.package schema.xsd

  • ArticleType.java
  • CatalogType.java
  • JournalType.java
  • ObjectFactory.java

ArticleType, CatalogType and JournalType correspond to the complex types defined in the schema. ObjectFactory is the object creation class which is used to create instances of the other objects. The one alteration that is needed is to add the @XmlRootElement annotation to the CatalogType class.

Here’s some sample code that uses this API to create a nice enough XML File and then reads it back to Java objects:

JAXBContext jaxbContext=JAXBContext.
                 newInstance("my.package");
Marshaller marshaller=jaxbContext.
				createMarshaller();
ObjectFactory factory=new ObjectFactory();
CatalogType catalog=(CatalogType)
	(factory.createCatalogType());
catalog.setSection("my catalog");
catalog.setPublisher("my publisher");

ArticleType articleType =
			factory.createArticleType();
articleType.setAuthor("an author");
articleType.setTitle("a nice article");
articleType.setLevel("rant");

JournalType journal =
		factory.createJournalType();
journal.getArticle().add(articleType);

catalog.getJournal().add(journal);
File file = new File("c:/jaxb2example.xml");
marshaller.
	setProperty("jaxb.formatted.output", true);
marshaller.marshal(catalog,
		new FileOutputStream(file));

Unmarshaller unmarshaller =
		jaxbContext.createUnmarshaller();
CatalogType c = (CatalogType)
	unmarshaller.unmarshal(file);

System.out.println("author is = " +
		c.getJournal().get(0).getArticle().
		get(0).getAuthor());

The XML file that gets generated and read conforms to the XSD:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<catalogType section="my catalog"
			publisher="my publisher">
  <journal>
    <article level="rant">
      <title>a nice article</title>
      <author>an author</author>
    </article>
  </journal>
</catalogType>

The compilation and runtime requires the following JAR’s in the classpath:

c:\Sun\jwsdp-2.0\jaxb\lib\jaxb-api.jar
c:\Sun\jwsdp-2.0\jaxb\lib\jaxb-impl.jar
c:\Sun\jwsdp-2.0\jaxb\lib\jaxb-xjc.jar

Damn easy.

Posted in java, tech | 19 Comments »