Simon Fell > Its just code > May 2006

Wednesday, May 31, 2006

SFGate has a great aricle on the coffee industry called A Cup of Hope: Coffee's Lessons. Here's a couple of choice extracts, definitly worth a read, if that pique's your interest, then make sure you get and see Black Gold if you get a chance.

Taken together, these labels amount to something we've never seen in any other sector: foreign policy on the supermarket shelf. As a coffee drinker, you can decide for yourself how you want the international trade undertaken on your behalf to be conducted.

The difference between fair trade co-ops and neighboring farms is stunning -- it can mean the difference between kids being able to go to school, where they can work toward a better future, versus malnutrition and toil for the entire family.

Monday, May 29, 2006

Somehow I think the thumbnail looks better than the larger version.

Monday, May 29, 2006

The tamper army lined up and ready for battle

Sunday, May 28, 2006

Yes, I'm enjoying the new camera, even a photo dummy like me can get some decent results. (the cactus photo is still my favorite) Now I'm spending most of my time on the mac, I burnt an evening importing my existing 2000 odd photos into iPhoto, its the most organized they've been to date. At some point i should start reading up on some of the 6 million settings, but not yet :)

Saturday, May 27, 2006

Wednesday, May 24, 2006

Saturday, May 13, 2006

just a test from the java/swt/osx version of relaxer, yes its hooked upto iTiunes already :)

Friday, May 12, 2006

I finally found a build of Eclipse that runs out of the box on an Intel Mac, 3.2 M5. Time to start work on a Java based version of Relaxer. And thanks to Nelson's blog about Thinner, i now have a bunch of new music to listen to while coding, I haven't downloaded a lot of it yet, but I really liked the Das Kraftfuttermischwerk stuff.

Friday, May 12, 2006

I have a massive reading backlog, I got a pile of books at christmas, then proceeded to buy another big bag of books while at Powells. I finished reading Accelerando by Charles Stross this week, I really liked it, a fast paced cyberpunk page turner, I couldn't put it down, I read Singularity Sky and Iron Sunrise last year and like those too, but I think Accelerando is better than both of those.

Tuesday, May 9, 2006

I was hoping that ADB would work for this, but apparently not, so XMLBeans it is, which is a pity because working with the xsd:any wildcard collections in xmlbeans seems to be fairly painful.

If you're looking for a java stack to call the sforce APIs, I really so no reason why you'd choose Axis2 over Axis 1.x, it may have better under-pinning, it may present a more pure model, but at the end of the day, its takes more lines (of tedious boiler plate code) to use, has more bugs and less features than the now almost 3 year old Axis 1.1. release. As the BileBlog says, why bother ?

Sunday, May 7, 2006

Axis2 1.0 was recently released, whoever is in charge of release numbers needs firing, why isn't it just Axis 2.0?, now we have Axis(1) 1.4 and Axis(2) 1.0, anyway I digress, I've been following the earlier builds and RCs, I haven't had too much time to try it out with all the sforce stuff yet, but here's a few pointers to keep you on the straight and narrow.

  • the default ADB databinding will not work with the sforce enterprise WSDL, because it can't handle complex types extensions, unfortunately it won't tell you this at WSDL2Java time, you get a rather more cryptic error at runtime, use the XMLBeans option instead (this is unfortunate because the xmlbeans model is even more verbose to use than ADB).
  • It supports HTTP compression out of the box (thanks Dims!), but I couldn't find any docs on how to turn it on, digging around, I got this to work.
    SforceServiceStub stub = new SforceServiceStub();
    stub._getServiceClient().getOptions().setProperty(HTTPConstants.MC_ACCEPT_GZIP, Boolean.TRUE);
    stub._getServiceClient().getOptions().setProperty(HTTPConstants.MC_GZIP_REQUEST, Boolean.TRUE);
  • You have to be careful with the order in which you put together your xmlbean instances (I don't know if this is an Axis2 thing, or an xmlbean thing, either way it seems fairly idiotic to me), e.g.
    LoginDocument ld = LoginDocument.Factory.newInstance();
    Login l = Login.Factory.newInstance();
    ld.setLogin(l);
    l.setUsername(args[0]);
    l.setPassword(args[1]);
    LoginResult lr = stub.login(ld).getLoginResponse().getResult();
    
    will fail because the generated message doesn't contain the username or password (does setLogin copy the Login instance passed in?), you need to do this.
    LoginDocument ld = LoginDocument.Factory.newInstance();
    Login l = Login.Factory.newInstance();
    l.setUsername(args[0]);
    l.setPassword(args[1]);
    ld.setLogin(l);
    LoginResult lr = stub.login(ld).getLoginResponse().getResult();
    
  • The stub no longer tracks the state of soap headers for you, you need to do this yourself and pass the relevant headers on each operation call, here's a quick sample that calls login, handles the redirect and sessionHeader, then calls query.
    SforceServiceStub stub = new SforceServiceStub();
    stub._getServiceClient().getOptions().setProperty(HTTPConstants.MC_ACCEPT_GZIP, Boolean.TRUE);
    stub._getServiceClient().getOptions().setProperty(HTTPConstants.MC_GZIP_REQUEST, Boolean.TRUE);
    		
    LoginDocument ld = LoginDocument.Factory.newInstance();
    Login l = Login.Factory.newInstance();
    l.setUsername(args[0]);
    l.setPassword(args[1]);
    ld.setLogin(l);
    LoginResult lr = stub.login(ld).getLoginResponse().getResult();
    		
    System.out.println(lr.getServerUrl());
    System.out.println(lr.getSessionId());
    	
    stub = new SforceServiceStub(lr.getServerUrl());
    stub._getServiceClient().getOptions().setProperty(HTTPConstants.MC_ACCEPT_GZIP, Boolean.TRUE);
    stub._getServiceClient().getOptions().setProperty(HTTPConstants.MC_GZIP_REQUEST, Boolean.TRUE);
    		
    SessionHeader sh = SessionHeader.Factory.newInstance();
    sh.setSessionId(lr.getSessionId());
    SessionHeaderDocument sd = SessionHeaderDocument.Factory.newInstance();
    sd.setSessionHeader(sh);
    		
    QueryDocument qd = QueryDocument.Factory.newInstance();
    Query q = Query.Factory.newInstance();
    q.setQueryString("select id, name, accountNumber from Account");
    qd.setQuery(q);
    		
    QueryResult qr = stub.query(qd, sd, null).getQueryResponse().getResult();
    		
    System.out.println("Query has " + qr.getSize() + " records total");
    Account a = (Account)qr.getRecordsArray(0);
    System.out.println(a.getId() + " " + a.getName() + " " + a.getAccountNumber());

I'll keep trying stuff out including the partner WSDL (which i'm hopeful will work with ADB), and keep you posted.

Sunday, May 7, 2006

I've ranted about this before, the next generation of WS stacks bring new programming models with them, and I can't for the life of me work out why someone thinks they're better than what's before. I keep hearing that's its a purer mapping to the message declarations in the WSDL. In which case, exactly what the fuck is the portType for in WSDL, in the brave new world it seems to carry zero semantic scope, other than mapping messages to URLs. Part of me is laughing so hard, the shinny new programming model is exactly what the PocketSOAP WSDL wizard has been generating for the last 4 years!, It works, but its painful to use, so much tedious boiler plate code, now new stacks like Axis2 and WCF (nee Indigo) and declare this model the best thing since sliced bread, I don't get it, is purity of model really worth all the extra boiler plate code you're asking everyone to code up ?, e.g. here's some Axis 1.x code to create a stub and call an operation that take 2 elements.

Soap svc = new SforceService().getSoap();
LoginResult lr = svc.login(username, password);

Here's the axis2 equivalent (using the xmlbeans databinding option)

SforceServiceStub stub = new SforceServiceStub();
LoginDocument ld = LoginDocument.Factory.newInstance();
Login l = Login.Factory.newInstance();
l.setUsername(args[0]);
l.setPassword(args[1]);
ld.setLogin(l);
LoginResult lr = stub.login(ld).getLoginResponse().getResult();

Yes, that really is 7 lines of code for the new and improved version vs 2 lines of code originally. Don't think I'm picking just on axis2, WCF is equally dumbass (to the point where one of the Indigo evangelists eventually backed down and said that the existing .NET WS stuff is better than Indigo for calling regular WS-I basic profile services!). Moving on in the code, the stub no longer tracks headers for you, each operation that takes soap headers has to have the set of headers passed into every operation. I can't imagine anyone using this stuff without writing an additional wrapper class that exposes an model like the earlier versions of the tools.

Wednesday, May 3, 2006

There's new releases of PocketHTTP & PocketSOAP, this fixes an intermittent problem where it would cause an access violation while parsing a response envelope. Thanks to Albert Chau and Matt Sell for their help tracking this one down.