Friday, February 27, 2009

Infer XSD from XML

Trang is a neat little utility to generate a matching XML Schema from an existing XML Document.

Usage is straightforward:
java -jar trang.jar input.xml output.xsd

Tool page is here. Manual is here. Code is hosted on google code.
The tool can do much more. Especially conversion between different schema languages...

Thursday, February 26, 2009

Braindeadness successfully achieved ...

226px-Wave.svg.png Today it was finally confirmed, that my journey to braindeadness was successful ... Im officially a Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5 ...

Actually it was quite a challenge, because even though my brain was already proven dead, I had to personally ask Sun support because it was not confirmed on certmanager after six weeks ... supposedly there were technical problems preventing my automated step into zombie land ...

I wish I had already reached the next level of salvation, and could actually make sarcastic comments about my achievements... oh wait, did I just do that? ... braindead ...

Wednesday, February 25, 2009

Web automation with Groovy and Ruby

For a small private project I need to do some web automation.

I wanted to use a scripting language and decided to give Ruby and Groovy a try.

In Ruby there is the Mechanize library. In Groovy there are different options.

The Ruby Mechanize library seems very intuitive:
  require 'rubygems'
  require 'mechanize'

  a = WWW::Mechanize.new { |agent|
    agent.user_agent_alias = 'Mac Safari'
  }

  a.get('http://google.com/') do |page|
    search_result = page.form_with(:name => 'f') do |search|
      search.q = 'Hello world'
    end.submit

    search_result.links.each do |link|
      puts link.text
    end
  end


I like the DSLish way to both, scrape (eg: earch_result.links.each) and manipulate (eg: search.q = 'Hello world') a web page.

In Groovy scraping is also pretty DSLish:
def page = new XmlSlurper(new org.cyberneko.html.parsers.SAXParser()).parse('http://groovy.codehaus.org/')
def data = page.depthFirst().grep{ it.name() == 'A' && it.@href.toString().endsWith('.html') }.'@href'
data.each { println it }
But it makes a bit a less concise impression than the Ruby version.

Manipulating a web page with groovy unfortunately is clumsier:
import com.gargoylesoftware.htmlunit.WebClient

def webClient = new WebClient()
def page = webClient.getPage('http://www.google.com')
// check page title
assert 'Google' == page.titleText
// fill in form and submit it
def form = page.getFormByName('f')
def field = form.getInputByName('q')
field.setValueAttribute('Groovy')
def button = form.getInputByName('btnG')
def result = button.click()
// check groovy home page appears in list (assumes it's on page 1)
assert result.anchors.any{ a -> a.hrefAttribute == 'http://groovy.codehaus.org/' }

This is less DSLish and much more old-scool imperative... the different styles for scraping and manipulating is a bit unfortunate (however you can also use HtmlUnit for scraping).

Tuesday, February 24, 2009

Go ahead, make my day!

SmithWesson.jpg Are you tired of a hard day working in the trenches of enterprise IT?
Are you frustrated for spending another day in a big ball of mud?
Is your brain filled with WTF from reading wagon-loads of legacy code?

Then I have the right thing for you. Go listen to Stackoverflow Podcast 41.

In corporate environments you are building products, that will never see the light of day in any meaningful way. They are only used by internal people for very narrow things. These are products that would never survive in the outside world. They are just that bad. They have bad features, they are not usable, they don't meet a real need, even to the business... yeah it's really sad ... if you love the stuff, if you are a thoughtful developer, you are in the wrong place!

In corporate environments the product don't have to be good. Sometimes they don't even have to exist ...

The corporate environments are awful!

Do you like some more? Then go along and read: Why Do Enterprise Applications Suck?

Ok, maybe it's time to call a shrink for some midlife-crisis-treatment ...


Do you think you have seen it all?

I actually have met people in our industry, that told me in all sincerity, that they know how to program, that they don't have to learn any more!

Well, I for myself don't think that I will ever reach that stage of bliss ...

Every day proves that the world in IT is far from settled.

Last autumn Adam Bien was giving a lecture about 'Designing The Boundary - Rich UI Meets Efficient Java EE Backend'. The heavily interactive UI of an IDE was the perfect example for an application, that should/must be realized as a Rich/Fat-Client...

... fast forward half a year ...

... say hello to the web based IDE.



Bespin, the web-based code editor from Mozilla is quite exciting, something I did not think would even be possible ...
And there is also herokugarden...

I am looking forward to do some heavy web-based code refactoring over the touch screen of my iPhone :-)

Thursday, February 19, 2009

I can offer a lot of that ...

Glass-of-water.jpg Once again I was loosing myself in blissful braindeadness (learning for the ISTQB Foundation Level Tester Certificate), when I stumbled over a term I actually liked:
Professional Pessimism

This is supposed to be a desired trait of a software tester...

... well, I think I can offer a lot of that :-). Probably enough to dedicate a new category to it ... we will see.

Wednesday, February 18, 2009

Agile, Lean ... wait a moment!

image_agile_plant.jpgOk, I am just repeating what others said before (as usual)... here, here and here.

For some time I was watching the real cool guys advancing beyond Agile ... the next cool thing promised to be Lean.

I was just nodding my head, thinking "bummer, I did not even really grasp Agile yet, and those guys are already over the next hill ... I have to hurry to keep up!".

But then the famous sentence "Hold it!" (remember 12 Monkeys?) was thrown at me in surprise:

Lean and Agile: Marriage Made in Heaven or Oxymoron?

Wait... did I not preach myself that the Software Factory Analogy fails? ... why did I not realize, that the manufacturing approach that Lean pursues is basically the Factory Analogy that is totally contradictory to my understanding of software creation?

Reading the article felt like scales falling from my eyes...

I actually like the analogy of software creation and theory building (originally by Peter Naur): The actual software is just a byproduct of the process of building an understanding of a given domain.

http://www.pbs.org/wgbh/nova/einstein/images/lega-emc2-l.jpg When you look at any formula in exact science, e.g. Einsteins Mass–energy equivalence, the first thing that comes to mind is a simple formula...

Looking from a Lean perspective, this fromula would be the only valuable thing. Every thing else is waste... but who does really understand the formula? Isn't the theory behind the formula the real value. Isn't the formula alone pretty useless without the context and the insights that were gained by developing it?



Friday, February 13, 2009

Rocky Lothka about Oslo

There are some funny quotes from Rocky Lothka in .NET Rocks Episode 417. When asked about what Microsoft Oslo is:
Oslo is a modeling tool that sits on top of a database that stores metadata and application data and blends it all together in one ball of wax ... wow, what I just described is Access!

And later about the future of the DSL movement:
Some DSLs will live and some DSLs will die...

Wednesday, February 11, 2009

Leaky Seam

Speed up your Data-Driven JSF/Seam Application by Two Orders of Magnitude is a very interesting article about improving performance in a web application.

It is a perfect example for the fact that powerful technologies layered on top of existing technologies are always Leaky Abstractions.

The cool thing however is, that all the problems could be solved by means that are provided by the used technologies. No hacks were necessary! I guess that speaks for Seam as a well designed framework…



Monday, February 9, 2009

The state of developer testing

We're still figuring this stuff out. All of us.

-Jay Fields


Each semester I am giving a workshop about testing Java EE applications at the SWS. This is almost exclusively about automated developer testing.

The sad thing is, that reality as I experience it in the trenches of enterprise-IT does not even remotely resemble the current ideas of developer testing.

Adam Bien calls this discrepancy between current testing ideas and the reality Schizophrenia Driven Design.

For a long time I have been believing that if we could become real masters of developer testing, life in the trenches of enterprise-IT would become paradise. If only we could achieve that ...

477931___red_pill__.jpg
But lately I feel like somebody gave me the red pill, I wonder if my trust in automated developer testing was just another desperate effort to cling to a naive fairy tale, where silver bullets actually exist...?


Here are just two more steps on my doomed journey of loosing my faith:

  • Luke Francis' excellent presentation Testing is Overrated (and the post and slides)
  • Jay Field's Thoughts on Developer Testing



  • Thursday, February 5, 2009

    DSLs - Are people loosing their faith?

    braindead-closeup.jpg Some month ago I was skeptical about lightheartedly jumping into DSL-creation, and I was wondering if I had lost my faith.

    It seems now that I am not the only one and the DSL movement is getting its share of scepticism:
  • Rocky Lothka (founder of CSLA): DSLs – fun, cool, but maybe a bad idea?
  • I like the analogy between creating a DSL an opening a restaurant here: DSLs: Definitely a bad idea! from Panopticon Central
  • The sarcastic YADSL Rule from Tiger Ops

  • Tuesday, February 3, 2009

    Help needed: Mapping a bidirectional list with Hibernate

    I don't understand the behavior of Hibernate when mapping a bidirectional list. The SQL statements that Hibernate produces seem not optimal to me. Can somebody enlighten me?

    The scenario is the following: I have a one-to-many parent-child relationship. I map this relationship with a bidirectional list.

    According to the Hibernate Annotation Reference Guide (Chapter 2.4.6.2.3. Bidirectional association with indexed collections) the mapping should look like this:
    @Entity
    public class Parent {
    
        @Id  @GeneratedValue private long id;
        @Version  private int version;
        private String name;
    
        @OneToMany(cascade = CascadeType.ALL)
        @JoinColumn(name = "parent_id", nullable=false)
        @org.hibernate.annotations.IndexColumn(name = "parent_index")
        List<Child> children = new ArrayList<Child>();
    
    	...
    

    @Entity
    public class Child {
    
        @Id @GeneratedValue private Long id;
        @Version private int version;
        private String name;
    
        @ManyToOne
        @JoinColumn(name = "parent_id", updatable = false, insertable = false, nullable=false)
        private Parent parent;
    
    	...
    

    But in this case Hibernate produces three SQL statements when persisting a parent with one child:
    Hibernate: insert into Parent (name, version, id) values (?, ?, ?)
    Hibernate: insert into Child (name, price, version, parent_id, parent_index, id) values (?, ?, ?, ?, ?, ?)
    Hibernate: update Child set parent_id=?, parent_index=? where id=?
    

    The third statement seems to be redundant, because parent_id and parent_index seem to be set already in the second statement.

    When I change the mapping and repeat the attributes 'updatable = false, insertable = false' to the declaration of the @JoinColumn in the Parent like this:
    @Entity
    public class Parent {
    
        @Id  @GeneratedValue private long id;
        @Version  private int version;
        private String name;
    
        @OneToMany(cascade = CascadeType.ALL)
        @JoinColumn(name = "parent_id", updatable = false, insertable = false, nullable=false)
        @org.hibernate.annotations.IndexColumn(name = "parent_index")
        List<Child> children = new ArrayList<Child>();
    
    	...
    

    @Entity
    public class Child {
    
        @Id @GeneratedValue private Long id;
        @Version private int version;
        private String name;
    
        @ManyToOne
        @JoinColumn(name = "parent_id", updatable = false, insertable = false, nullable=false)
        private Parent parent;
    
    	...
    

    ...then Hibernate seems to produce much more optimized SQL:
    Hibernate: insert into Parent (name, version, id) values (?, ?, ?)
    Hibernate: insert into Child (name, price, version, parent_id, parent_index, id) values (?, ?, ?, ?, ?, ?)
    


    The client code looks like this:
            EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");
            EntityManager em = emf.createEntityManager();
            EntityTransaction tx = em.getTransaction();
            tx.begin();
    
            Parent newParent = new Parent();
            newParent.setName("Parent1");
    
            Child newChild = new Child();
            newChild.setName("Child1");
    
            newParent.getChildren().add(newChild);
            newChild.setParent(newParent);
    
            em.persist(newParent);
    
            em.flush();
            tx.commit();
    

    I am using hibernate-entitymanager 3.4.0.GA.

    What am I missing? Is the Hibernate Reference Guide not correct, or am I overlooking something?

    Update 2009-01-06:
    Ok, I was not reading the Annotations Reference Guide thoroughly enough.

    In Chapter 2.2.5.3.2.1 it is stated clearly:

    To map a bidirectional one to many, with the one-to-many side as the owning side, you have to remove the mappedBy element and set the many to one @JoinColumn as insertable and updatable to false. This solution is obviously not optimized and will produce some additional UPDATE statements.

    It probably would not hurt to repeat this information in Chapter 2.4.6.2.3 .

    But a question remains: If I repeat the @JoinColumn attributes 'updatable = false' and 'insertable = false' on the Parent (see code above) the additional update statements seem not to get produced... is this a legitimate workaround? Or does this result in another problem?
    Related Posts Plugin for WordPress, Blogger...