Monday, May 12, 2014

What's wrong with JavaServerFaces

When we click on the “homepage” link of the JSF entry in Maven Repository we are forwarded (from http://java.sun.com/javaee/javaserverfaces/ - I thought that company died long ago, but Oracle doesn’t bother fixing links) to
http://www.oracle.com/technetwork/java/index.html
which currently showcases a picutre of a young man in front of the computer
enter image description here
and we are told he is probabaly working with JSF & PrimeFaces (PrimeFaces is “a popular JavaServer Faces (JSF) UI framework” that is also used in my project, I hope I’ll get to cover that too).
Now, to me, he doesn’t look like he is happily working on something interesting but rather trying hard to finally get-that-bloody-thing to work (already in the exhaustion/resigning phase – “damn, why doesn’t it work!? :(“).
This is comes close to how I feel about the series of tools I am writing about here (1).

So let’s get started tinkering about this web framework.

Wow, I cannot read on, obviously that webpage is not meant to be looked at when seriously trying to learn about jsf.

Looks like http://docs.oracle.com/javaee/7/tutorial/doc/javaeetutorial7.pdf is not too bad a place to start.

To be continued…


(1): Combined with the feeling that “it cannot be so hard to make this better, let me show you”

Written with StackEdit.

What's wrong with Maven

In the project I have to work on mentioned in the last post, there are of course other technologies and tools used besides Hibernate that I have to learn (I do not come from a Java programming background so most of these are (though not conceptually) relatively new to me).
One of them is the buildtool Maven. Let’s see what flaws we can find with Maven:

  • It’s ironic how their philosophy is “don’t repeat yourself” yet they use xml for the configuration where up to half of the filesize comes from repeating words for the closing tags (yes I know that’s not what they mean).
  • They make users to define custom “properties” with custom tags. Within a pom.xml file you can write:

    <properties>
        <myfaces.version>2.1.12</myfaces.version>
        <mojarra.version>2.1.23</mojarra.version>
        <myweirdpropertythatiwillnotuse>42</myweirdpropertythatiwillnotuse>
    </properties>
    

    where myfaces.version etc. is the name of the property I want to define. Not only do I have to repeat myself here, but the notation is not even used consistently to refer to properties and their values. In settings.xml, for a check whether a property matches some value, you write

    <activation>
        <property>
            <name>target-env</name>
            <value>dev</value>
        </property>
    </activation>
    

    And we shall not forget that all the other tags used are static. I don’t even know how they got their dtd or xslt or whatever we have here to swallow this.

Btw: I have never liked and will never like xml for all its bloat and way too many ways to do things (with no visible benefits of one over the other): You can set data by:

  1. Using user defined tags.
  2. Using tag attributes.
  3. Using nested tags.
  4. Any weird combination thereof.

Also people don’t stick to one standard for writing lists of values. Sometimes they pack everything in an attribute value, leaving other programs to parse it (svg…), sometimes they go

    <activeProfiles>
        <activeProfile>alwaysActiveProfile</activeProfile>
        <activeProfile>anotherAlwaysActiveProfile</activeProfile>
    </activeProfiles>
    <repositories>
     <repository>
     </repository>
    </repositories>

repeating the outer word in singular in the inside, sometimes not:

  <properties>
    <tomcatPath>/path/to/tomcat/instance</tomcatPath>
  </properties>

Even worse, they sometimes even make use of the fact that <a>hi<br/>there</a> is parsed as one node with three children, two of them unnamed.


Proudly written with StackEdit.

Friday, May 09, 2014

Why Hibernate is a disaster

I am forced to work with this Java Object Relational Mapping “solution” (a collection of functions, annotations and configuration hell to try to fit the round peg of object oriented programming into the square hole of relational databases) for the next 4 months (2 already done - luckily). And I really have not much to say in its favor.

  • Read http://empire-db.apache.org/empiredb/hibernate.htm: The use of annotations and strings to provide information is a bad choice. The former because it cannot be modified or easily read at runtime (only through awkward interfaces), the latter because it is only checked at runtime, which means never for the 90% of the code that are run 10% of the time (don’t comment with “well you need unit tests”).

  • The developers of Hibernate have never heard of the Law of Demeter.

    session.buildLockRequest().setLockMode(LockMode.PESSIMISTIC_WRITE).setTimeOut(1000 * 60).lock(entity);
    

    They used method chaining (the “builder pattern”) extensively.
    http://stackoverflow.com/questions/1103985/method-chaining-why-is-it-a-good-practice-or-not

  • The Criteria API is a distaster http://docs.jboss.org/hibernate/orm/4.2/devguide/en-US/html/ch12.html
    Tell me you get what these queries do without looking at the documentation:

    CriteriaQuery criteria = builder.createTupleQuery();
    Root personRoot = criteria.from( Person.class );
    Path idPath = personRoot.get( Person_.id );
    Path agePath = personRoot.get( Person_.age );
    criteria.multiselect( idPath, agePath );
    criteria.where( builder.equal( personRoot.get( Person_.eyeColor ), "brown" ) );
    
    List tuples = em.createQuery( criteria ).getResultList();
    
    CriteriaQuery query = builder.createQuery();
    Root men = query.from( Person.class );
    Root women = query.from( Person.class );
    Predicate menRestriction = builder.and(
      builder.equal( men.get( Person_.gender ), Gender.MALE ),
      builder.equal( men.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE )
    );
    Predicate womenRestriction = builder.and(
      builder.equal( women.get( Person_.gender ), Gender.FEMALE ),
      builder.equal( women.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE )
    );
    
    query.where( builder.and( menRestriction, womenRestriction ) );
    

    and even if you do, tell me why I have to call “builder.” all the time.
    Well that’s because Java just wasn’t made for building code like that - which should have been clear from the start.
    Their older api seems to have been slightly better:

    List cats = sess.createCriteria(Cat.class)
        .add( Restrictions.like("name", "Fritz%") )
        .add( Restrictions.or(
            Restrictions.eq( "age", new Integer(0) ),
            Restrictions.isNull("age")
        ) )
        .list();
    
    List cats = sess.createCriteria(Cat.class)
        .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
        .add( Restrictions.disjunction()
            .add( Restrictions.isNull("age") )
            .add( Restrictions.eq("age", new Integer(0) ) )
            .add( Restrictions.eq("age", new Integer(1) ) )
            .add( Restrictions.eq("age", new Integer(2) ) )
        ) )
        .list();
    

    But what does the word “Criteria” have to do with the notion of a database query?

  • Of their guides and docs I have looked at, the “Getting started guide (brief)” is a joke, “Getting started guide (full)” too and “Developer’s Guide” is hard to read, incomplete and full of spelling mistakes.

  • The javadoc documentation for the most important class “Session” is poorly written, e.g. referring to this interchangably (and patternless) with any of “the current session”, “this current session”, “the session”, “this session”.
  • From the javadoc

    Change the default for entities and proxies loaded into this session
    from modifiable to read-only mode, or from modifiable to read-only
    mode.

    (Yes, it is twice the same.)

  • Flags are either documented as “Checks” or Questions:

    Session::isConnected()
    Check if the session is currently connected.

    Session::isDefaultReadOnly()
    Will entities and proxies that are loaded into this session be made read-only by default?

    (not to mention that javadoc doesn’t recognize the ? as ending a sentence and therefore goes on to find the next dot).

  • Spelling mistakes even in the javadoc: In Hibernate.Query:

    … to Hibernate types using hueristics.

  • In Query, the methods taking LockMode are not deprecated, unlike in Session.

  • Everything throws HibernateException, there is no way to differentiate between these programmatically excpet with their message strings - for which of course you will only know (if you are lucky) at runtime that you spelled them wrong.

  • getNamedParameters()
    Return the names of all named parameters of the query.

    Obviously, this method should have been called getNamedParameterNames() [let’s not discuss the poor naming choice], then the documentation would be moot. But if I read get(Named)Parameters, I think of getting their values.

  • The forum consists only of spam (first non-sticky entry in “Hibernate Users”: “Watch Frozen Online Free”). Which is also why I did not post all of that there.

I think I could go on. Unfortunately I don’t have the time nor the creativity to write as entertaining a rant as “PHP A fractal of bad design
Maybe I will wrap this up one more time once I’m done with it.

PS: Wow, the blogspot editor is annoying to use too, copying the style of the text I paste - can I turn that off? Please forgive the terrible formatting.

Edit: Now using https://stackedit.io to write my entries with markdown.