Notes on Curl: Testing a Webservice
September 16th, 2008msg=`cat soap-msg.xml`curl -H “Content-Type: text/xml;charset=UTF-8″ -d “$msg” http://foo.com/webservice/
msg=`cat soap-msg.xml`curl -H “Content-Type: text/xml;charset=UTF-8″ -d “$msg” http://foo.com/webservice/
Today I finally got around to updating my resume. This is something that I never enjoy doing. Aside from basic polishing I added my Ruby and RoR experience. At the moment I still can’t say I’m onboard the RoR bandwagon, I do however find Ruby an interesting and fun language.
Tapestry 5 has seen a lot of updates over the past couple of months. With the addition of the Autocomplete mixin and the Zone component, AJAX is becoming evermore supported and ingrained. When writing AJAX components, using the Autocomplete source as a reference to “how it should be done” is a great thing to do. It’s concise, simple, and shows that AJAX components are on their way to feeling very natural. AJAX event handlers for components behave much the same as they do for normal ones, with the addition of a few new options in the return type. Tapestry makes it easy to respond with JSON objects, in that you can return a JSONObject:
Object onUpdatelist() {
JSONObject messages = new JSONObject(
"{users:[{user: 'clewis', firstName: 'Chris'}]}");
return messages;
}
Nice. However there is another type that would be a very natural return type, JSONArray (not supported as of r638979). I say this because it’s already available in the API, and developers quite often need to return collections of (JSON) objects. So, why not support JSONArray return values? As it turns out, adding this support is not at all difficult, so today I opened a ticket and provided a patch to do just that. Check it out at: https://issues.apache.org/jira/browse/TAPESTRY-2286. The patch updates tapestry’s configuration module, and requires the additional class. With this addition you can now return JSONArrays, without the bother of wrapping your list in a useless object:
Object onUpdatelist() {
JSONArray messages = new JSONArray("[{user: 'clewis', firstName: 'Chris'}]");
return messages;
}
Of course even without compiling this into tapestry, you can provide this class and wire it up through your own module.
Dealing with gpg public and private keys has been a bit of a pain for me in the past. It’s not a complicated matter really, using them, it’s just that when the time comes for me to renew or create a key pair, I never remember any of the gpg commands! I just went through the process and decided to write a quick post about it.Assuming you’ve created your key pair, you can enumerate your key (and any others in your keyring).
chris-lewis-computer:~ chrislewis$ gpg --list-keys /Users/chrislewis/.gnupg/pubring.gpg ------------------------------------ pub 1024D/875E0AD6 2008-02-25 [expires: 2008-08-23] uid Chris Lewis (burningodzilla)[ removed ]
Now that you know about your keys, you have the names. Above you see my public key’s name: 875E0AD6. I can now dump it in a printable (ascii-armored) format:
chris-lewis-computer:~ chrislewis$ gpg --export -a 875E0AD6 -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.7 (Darwin) mQGiBEfDIhIRBAC25JPhhfz6y86Jj5l6nwb5WQ6+4PDanuuF6fGPzSRLGlcnNF5m 4UUawqF1Ofvlo4RGFkNRfRo/xdiqh95oS75rFD8hZAAyoj4CJ+NTtaTunrW+X9K2 olhV2Mf4L4b1PTJWUAcErCZg9SM/BleSCQQjmnJpPZ7JWjSlPOZhwXP0nwCg5Vwt NHu+rD7mOGFDFNI81RHFhU8EAIveXe1MhSnB2pxF+r0IzHJIXC0a+buUpJB28Tef T5hRHYT5KS2Gcy7aGWeHqHnVQzDnIP1/sJ+vWrcjAHXFSBbgnXRqh/wBb+B8+IX9 qi30I1LIYdf8XMBpyMAl7XFf1Ee2N18dZgS7lI4Jz88Hzyn+aIIbZ6E1wyfCTcN2 uqnZA/9VDJ86n92Paa2AeyRQNsMK6xApZbndD+FjEOXb/WLPylgVQo22/46cpnW2 mqcPkOX5yHvFYJRH5K759NYG+ZAeLx5P7lXx8RZEHOjTvUpBL+OcVlfouFV8ozs7 DOLsBimTN/g/THiz6OWP0n6yahVpXTgbCIfDJRomQuss1MD4bbQzQ2hyaXMgTGV3 aXMgKGJ1cm5pbmdvZHppbGxhKSA8Y2hyaXNAdGhlZ29kY29kZS5uZXQ+iGYEExEC ACYFAkfDIhICGwMFCQDtTgAGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRAAZ67s h14K1itvAKDHO/Knhk2dKw/xhGUuVyM8A1su4ACeKxpWpx/Suf2aUNo+FT4cxeMv Dlu5Ag0ER8MiEhAIAPN7rqN+UZdvQDj1zmbYttWaQIHdHVdFzDWJZjC7KhxZuD/9 fmQGIItxECDnf4sObNxHckCIOP6WOENBq7iyUhZlImLOlPcxXUjPG1wz5q28iUAo wFXy9ftGVPYJWT84LOS0Ut9lhfG8irmYCR9I1Q0Z2G0mZ9Ftv398u/FbET43bpVh NJKcNN0kvsoEcQyTAvNmzfY8m79985W8AkuIAQMhoxYsMYv+ILI+vy49uJbWHpKN SIf39w/nAOhJIxbRLPR2ss58aHtLb4vA5wfMOiWSOvmiPbe3rEQFjk9/ORKbqc1I DGK4cx3EmOCDQ9WYpEbiv6/9ShdoY+gBSkD5h9MAAwUH/3qRxCGJ+NlVCFrkFNHu 0TV36B1UCLdPYiK4JLtaLBe+NNDf9YlPqYAZRuV9XH4LytwYqKtizS9AGDfidmhz rl5InYWjMqZkyG6FQI0E8y/RiqIo/DvButM21TsL5ciXTm/NOUecp7oNOL5pLwyJ 3JVOZQ74yqEXbV9hE0jc72CNQ2AeL0FnIHOPoD3onMF5zisdTFg71mOaXa4b+Urn Bt43dxU27psK+Cw+5OQxPIXBHl/aOrEght5qhu43oDB2BRu8N9M0a9hJ9ZWt7qD2 jjSj5e3039iOBP4xUNIuW30E1GcOG93q2B9QMenYbPKTZtDjOsmwZl3zGw8IENHX Ep6ITwQYEQIADwUCR8MiEgIbDAUJAO1OAAAKCRAAZ67sh14K1mnCAKCU6oWEEtKS GZDGU/JVmcYvT0K7zACgswx0Ng2uWc7dRPaVH52BM485GYA= =/cLY -----END PGP PUBLIC KEY BLOCK-----
And that’s it. FYI, that is my real public key.
In an attempt to keep a somewhat vibrant blog about my professional (and nerdy personal) life, I’m writing to share my involvement in a small open-source project: tapestry5-components. This is a component library for the much-anticipated Java web framework, Tapestry 5. Today I officially joined the project and merged my code into the svn repo. This code was from a much smaller component library I started called gc-tapestry-components. I will work on this project in free areas of time (as they arise), and even though my contributions may be small at first, I will strive to keep them significant.
I’ve uploaded a Mac package (pkg in a dmg) of the Fondu font utilities. Among other things, these utilities can convert mac .suit font files (archives) into true type (ttf), suitable for systems like Linux or Windows. Grab it from the Downloads page.
So here’s the deal - thus far in my career I’ve experienced the most satisfaction when developing applications in Java. Specifically, desktop applicaitons in Swing as well as some stand-alone server applications (not web apps/servlets). Of all the gripes and pains of Java, it is a proven, time-tested platform that has gained (and retains) a huge amount of support from 3rd party vendors and enterprise customers alike. Additionally, the developer ecosystem around Java has been on the forefront of software architecture and promoted the wide adoption of language constructs/paradigms such as AOP (No, the Java ecosystem did not invent or discover the concept of design patterns or aspects, but it is one of the most prominent responsible for the mass adoption of such practices over the last decade or so). I personally have learned and continue to learn from this ecosystem. While it has certainly not dictated my growth as a software developer, it has influenced it.
When I started looking in to web programming, a friend of mine turned me on to PHP. At this time I had probably been developing software for 2 years, so I was open to absolutely anything. Being that I didn’t have any push or guidance towards servlets or JSPs (my schooling focused on Swing and applets), I gave it a go. I very much enjoyed learning PHP. It was easy to set up, easy to learn, and fun to code. When I started getting into databases (MySQL of course), I saw the greater potential of PHP and, as many a fledgling developer, thought I was ready for anything with my new tools. I wrote several sites in PHP; raw, frameworkless PHP, and was happy with them. It wasn’t long before I noticed all the issues with this kind of development, none greater than the rigidity of the applicaitons (due to cut-past code, tight coupling, etc). For a year or two I used various tools and frameworks to improve the situation, but I have never been satisfied (my experiences and gripes with such tools, including mojavi, eclipse db, and cakephp, is beyond the scope of this post). On top of this I have developed a general distaste for PHP, and specifically its continued identity crisis as a language.
This laid the foundation for my investigation of J2EE (specifically servlets and JSPs). I had already used some J2EE components (including JDBC), but had yet to tinker with a container or to create even a Hello World servlet. After reading and working through “Core Servlets and Java Server Pages,” I wasn’t convinced this path was any better than my current one, so I didn’t make a transition. In fact it seemed about the same, with the additional overhead of compilation and the general pains of a servlet containers (deployment, reloading, etc). As such I continued down the same frustrating path of PHP, using cakephp as the framework as it at least sped development.
Of course during this time Ruby on Rails had emereged and had begun to take the web world by storm (at least in the tinkering sector) (It was RoR that led me to cakephp, as I was not interested in learning a new language or any of it’s surrounding technologies). I have investigated RoR, and while there are some clearly useful innovations, I’m simply not sold on ActiveRecord or it’s interpretation of MVC (specifically its whole controller/action paradigm).
There are other praises and complaints I have about RoR and related spin-offs, but that’s not what this post is about. What it is about is my repeated attempts to find a sane transition from PHP to Java/J2EE, when much of the world is taking an inverted path (not specifically to PHP, but to lightweight technologies like it or RoR). I believe I have found this path via Apache Tapestry.
Oddly enough, I discovered Tapestry through a PHP framework heavily influenced by it (Prado). I’ll go ahead and state that to date, no framework has made database interaction as quick or easy as RoR, including Tapestry. In fact, Tapestry provides no persistent layer at all, which is admittedly a drawback (note that the upcoming version 5 includes a tapestry-hibernate jar, but I’m not sure what all it does). If you want praises on Tapestry, try google, but what I will say is that getting started with it (version 4.1.2) is pretty simple. Get set up with Eclipse 3.3, Tomcat 5.5, and the Tomcat/Eclipse plugin, throw in the example chapters from EWDT, and you’re on your way. I bought the full book and it was well worth it.
I’ll close with a few statements that will hopefully add some cohesion to this post. Tapestry provides a way for me to impelement web applications on a J2EE stack, without having to invest so much time in digesting the staggeringly large J2EE spec. It also provides a fasinating paradigm to develop applications in, namely it’s component-based approach. An added bonus is the fact that I can share code between web and thick client apps where it makes sense to do so.
Will I invest time in digesting more of the J2EE stack? Most likely, but with Tapestry I can start develping effectively without first spending so much time mucking around in the massive spec that is J2EE.
I ran in to an annoying bit of behavior while working on a generic hovering element effect in Safari, using Prototype.js 1.5. Firstly, I’m not well-studied in the general quirks of the onload and unload events, how they work and should work etc, but this issue seems to stand outside that.
The code I’m working on uses the wonderful document.getElementsByClassName to locate the exact element to operate on. Everything was working smoothly, save for the usual and expected cross-browser kinks to be sorted out. Basically I have an element structure like this:
<div class='news-summary'>
<div class='title'>Today's News</div>
<div class='date'>5/18/2004</div>
<div class='summary'>This is a great post...</div>
<div class='admin-toolkit-canvas'>
<a>Edit</a>
</div>
</div>
This represents a simple news preview or summary, possibly one in a list that you might find on a news post index or a side element or portlet. Now if you are logged in as an admin, hovering over the summary should cause a translucent canvas to appear over it, containing easy to access admin functions (like edit). The css class news-summary is a top-level container for summary content, and contained in this is an element of class admin-toolkit-canvas. This element is invisible, and is positioned absolutely within the parent news-summary element. When any child element of the summary element is hovered over, the canvas is rendered. I use document.getElementsByClassName to locate the actual canvas element in various contexts, mainly for showing/hiding it. I had no serious issues until navigating away from the page in the same window, and then using the ‘back’ button in Safari to return to it.
It seemed that the hover events over the summary containers were no longer being handled properly, or more likely that the code I had written to locate the child canvas was breaking.
After some precursory investigation I had assumed this was a side affect of Safari’s handling of the onload event, but further experimenting proved otherwise.
Prototype does some things that some call bad practice, like augmenting core objects and classes provided by the browser environment. One such victim is the global document object, which it equips with the getElementsByClassName method. It works fine… until you return to a page using this method via the back button. So what’s the problem? The augmentations to core objects (not classes), specifically on document made by prototype are apparently reverted. That’s right. No more getElementsByClassName. Why? I’m not sure. This seems to be how WebKit is designed - to blindly (re)initialize the core objects on any page visit.
Is this a bug or a feature? I’m not yet sure. I haven’t done any other tests outside this, nor have I tried the WebKit nightlies. IE and FF seem to work as expected. More to come on this, no doubt. Share some input if you have any!
Cake is a decent framework. In fact I have very little gripes about it all around - plently of little picky things, but only one that really bugs me: cake’s model implementation.
Cake’s finders inherited by all models (find, findAll, etc) return 3d hashes, keyed at the top by the model class name, the middle with field names (model properties), and the bottom with the field values. This is a nice simple way of handling things, and does indeed work well for smaller applications. I’ve worked on several that attest to its usefulness (http://rosaloves.com for one).
Now for the rant: This Does Not Scale. Because we must deal in arrays instead of objects, we lose two very important OOP abilities - encapsulation and polymorphism. Our result models are not objects, so they are incapable of such notions. We have no typing, no method signatures, and therefore no effective interface. All entities must then have intimate knowledge of how our model is composed. There’s no point in getting into why this is bad - it has been documented over and over since the inception of OOP.
Why arrays? I am not involved in Cake’s development (though I hope to be an accepted contributor soon), so I can’t speak for them. In comparison with Ruby on Rails, I will wager a guess. Firstly, Rails’ finders are basically static methods (static as in Java), called class methods in Ruby, if I’m not mistaken. These methods only exist once in memory, as opposed to instance methods, which exsist per object instance. Static/class methods cannot operate on instance data (at least in Java, where ‘this’ is invalid). I’d wager that Rails’ finders/savers, as well as all relational mapping metadata, are static class members. This way model instances don’t carry (duplicate) this data per instance.
Php 4 can’t do this, not cleanly or naturally anyway, so Cake uses model instances singularly, probably to emulate the feel of executing finds in Rails. If Cake returned model instances (which it should), each instance would carry copies of the relational mapping data. If Cake exploited php 5, this metadata could be static and therefore shared between all instances of the model class. This could be achieved in a few ways in php 4, but it would be messy to say the least.
I’m only guessing that this is one of the reasons Cake does what it does. I’ll continue with a later post going further on thsi topic, as well as get into a project I’ve started on CakeForge called Object Model (http://cakeforge.org/projects/object-model/).
Blog is back, this time with a proper look. All the old content has been dumped, mainly because it was useless fluff to satisfy my experiment with wordpress.