Tuesday, September 13, 2011

Modular Web Application based on JBoss Modules

Recently I read Why there is no standard for developing real modular web applications? by Patroklos Papapetrou. Inspired by this article I decided to check JBoss Modules in action. This post describes my experiment step by step.

I've started with following goal in mind - create web application using some service defined by my own JBoss module. Service prepared by me was pretty simple,  I named it Echo Service:


and placed into separate jar file, named echo-api. Then I implemented this service:


and placed the implementation in new jar file, named echo-module. Having in mind that my web application should have knowledge about the service API only, not the specific implementation, I decided to go the way described in Creating Extensible Applications With the Java Platform - that choice required adding to echo-module jar special file under: META-INF/services/warlock.echo.EchoService, holding the "pointer" to the service implementation (fully qualified name of implementing class).

At this point, I've retrieved and unpacked JBoss Application Server 7, stepped into unpacked JBoss, and then into modules directory. In this directory I've added following structure:


Two jar files visible here are mentioned above, module.xml file is the definition of my JBoss Module - named 'warlock.echo', and has following content:


After completion of JBoss Module definition, I've prepared simple Spring Framework based application (which uses echo-api jar only during the compilation of project and doesn't use the echo-module jar at all) with only one Controller:


As you see the Controller returns as response body the result of Echo Service call for some string. Now to the most important part - Echo Service definition in Web Application:


I know, one thing is bothering you :) - how the hell will Echo Service implementation be found if we don't add either echo-api and echo-module jars to the Web Application?!

Well, this is the beauty itself ;) - We just need one more thing - WEB-INF/jboss-deployment-structure.xml file:


This way we tell JBoss - this application depends on the 'warlock.echo' module and the services defined in this module. The rest is pure JBoss Module magic ;)

Lectures for the dessert:

Tuesday, August 16, 2011

JBehave - quick BDD example

After few last months of work on some projects with Spring MVC, Spring WebFlow, and JPA I had to do something else ;) - even for a while ;) - below you may find a results of my small experiments with Behavior Driven Development and JBehave :)

I started with Introducing BDD and What's in a Story? articles by Dan North, and Alex Soto blog entry about Spring Framework, JBehave and Selenium 2 integration.

Then I asked myself: "What I need for the BDD experiment? - The Story :) - I borrowed one from Dan's article What's in a Story?. Suppose that we have an Account, Card bound to this account, and ATM which will dispense some money. In order to get money when the bank is closed, as an account holder I want to withdraw cash from an ATM - this is the story :) - This story will have 3 possible scenarios in my example:


As you see, this story and the scenarios included are written in human language :) - no programming here, it can be written by anyone! OK, but where is the development here?! - Give me few minutes, and I'll explain that :)

Each Scenario consist of 3 steps: Given, When, Then. First one (Given) defines the context of the specific scenario (ex. "the card is disabled"), second (When) defines the event which occurred in this specific context (ex. "the account holder requests 20"), and third one (Then) defines the state of the context after the event processing (ex. "the ATM should retain the card").

Each scenario's step is bound to the Java code responsible for "implementing" it, in our example:


When you look at the @Given, @When, and @Then annotations you'll see that their values are matching the content of scenario steps written in human language - and this is the point where human language used by your Business Development Team meets the "Real Developers" ;)

Now what? - the rest is easy :) - Alex Soto proposed in his article (Spring Framework, JBehave and Selenium 2 integration) that we can use the Spring Framework driven Components for holding the Steps, this is very nice idea, and sufficient in my example (I would worry about it only in multi-threaded environment, because Component build by Spring is a Singleton by default, and that's usually not a good idea in such  environment).

Spring Framework configuration:


We perform the component scan here (which will register bean for our Steps holding class), and define only one bean related to JBehave, configuring its report builder.

Now we need a code which will allow us to run the Story processing as JUnit test:

When you run this test, all scenarios will be verified, and along with the JUnit test result, JBehave report will be produced:

Few links for the dessert:

Saturday, June 25, 2011

JPQL and joins

Have you ever asked yourself if JPQL (Java Persistence Query Language) queries written by you REALLY do what you want, or you just prepare them, commit to the code repository, and forget about them with a little help from pizza and beer ;) ...

Let's take a look at very simple example, we have Person entity:
@Entity
@Table(name = "PERSONS")
public class Person implements Serializable {

    private String firstName;
    private Long id;
    private Person spouse;

    @Column(name = "FIRST_NAME")
    public String getFirstName() {
        return firstName;
    }

    @Id
    public Long getId() {
        return id;
    }

    @OneToOne(optional = true)
    @JoinColumn(name = "SPOUSE_ID")
    public Person getSpouse() {
        return spouse;
    }
...
}
and we want to fetch all persons matching some criteria.

Suppose that PERSONS table has following entries:

ID SPOUSE_ID FIRST_NAME
1 NULL John
2 NULL Mary
3 4 Adam
4 3 Eva

We will build and execute very simple JPQL query:
Query query = entityManager.createQuery(
    "select person from Person person where person.spouse.firstName = 'Eva' or 1 = 1");
Assert.assertEquals("Result list is too small,", 4, query.getResultList().size());
Our JPQL query should return all persons from the database, because of the "1 = 1" expression in where clause. Let's try how it works with different JPA Providers.

EclipseLink (2.2.0) converts our JPQL query into following SQL query:
SELECT t1.ID, t1.FIRST_NAME, t1.SPOUSE_ID 
FROM PERSONS t0, PERSONS t1 
WHERE (((t0.FIRST_NAME = 'Eva') OR (1 = 1)) AND (t0.ID = t1.SPOUSE_ID))
which leads to assertion error:
java.lang.AssertionError: Result list too small, expected:<4> but was:<2>small 
Hibernate (3.4.0 GA) uses following SQL:
select person0_.id as id1_, person0_.FIRST_NAME as FIRST2_1_, person0_.SPOUSE_ID as SPOUSE3_1_ 
from PERSONS person0_, PERSONS person1_ 
where person0_.SPOUSE_ID=person1_.id and (person1_.FIRST_NAME='Eva' or 1=1)
which leads to the same assertion failure.

Only OpenJPA (2.1.0) uses SQL expected by us:
SELECT t0.id, t0.FIRST_NAME, t1.id, t1.FIRST_NAME 
FROM PERSONS t0 
    LEFT OUTER JOIN PERSONS t1 ON t0.SPOUSE_ID = t1.id 
WHERE (t1.FIRST_NAME = 'Eva' OR 1 = 1)
How can we force EclipseLink and Hibernate to use left join? We have to modify JPQL query in following way:
select person 
from Person person 
    left join person.spouse spouse 
where spouse.firstName = 'Eva' or 1 = 1
As you see I've added explicit left join and changed first where clause expression to use this join.
Now JPQL query returns all 4 records regardless of used JPA Provider.

Monday, June 13, 2011

Customize PMD in Eclipse with your own rules

PMD is very nice Java code scanner which helps you avoid potential programming problems. It can be easily extended to your needs, and this post will bring you simple example of custom PMD rules related to JPA's @Enumerated annotation usage.

Before you'll continue the reading, you should check one of my previous posts - JPA - @Enumerated default attribute. When you work with the group of people on JPA project, it is almost certain that one of the developers will use @Enumerated annotation without defining the EnumType, and if you don't use strict data validation on the DB level (like column level constraints), you will fall into deep troubles.

What we would like to achieve is reporting an error when one uses @Enumerated without the EnumType:
@Entity
@Table(name = "BENEFITS")
public class Benefit implements Serializable {
    ...
    @Column(name = "BENEFIT_TYPE")
    @Enumerated
    public BenefitType getType() {
        return type;
    }
    ...
}
and a warning if one uses @Enumerated with ORDINAL EnumType:
@Entity
@Table(name = "BENEFITS")
public class Benefit implements Serializable {
    ...
    @Column(name = "BENEFIT_TYPE")
    @Enumerated(EnumType.ORDINAL)
    public BenefitType getType() {
        return type;
    }
    ...
}
We can achieve our goal in two ways, either describing the PMD Rule in Java, or using XPath - I'll focus on the second way in this post.

Let's start from the beginning ;) - we have to download PMD first (I used version 4.2.5,  pmd-bin-4.2.5.zip), unpack it somewhere, change the working directory to the unpacked PMD directory, and run the Rule Designer (it can be found in ./bin/designer.sh). You should see something like this:


Let's put the code we want to analyze into the source code panel, and click "Go" button:


In the middle of Abstract Syntax Tree panel you may see: Annotation / MarkerAnnotation / Name structure corresponding to our @Enumerated annotation without defined EnumType. To match it we will put into XPath Query panel following XPath expression:
//MarkerAnnotation/Name[@Image = 'Enumerated']
When you click on the "Go" button now:


you will see at the bottom right panel that the match was found :) - XPath Query is correct :).

Now when we have the XPath Query we have to define the rule using it, let's open new XML file, name it jpa-ruleset.xml, and put into it:
<ruleset name="JPA ruleset"
    xmlns="http://pmd.sf.net/ruleset/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
    xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
    <description>JPA ruleset</description>
    <rule name="AvoidDefaultEnumeratedValue" message="By default @Enumerated will use the ordinal." class="net.sourceforge.pmd.rules.XPathRule">
        <priority>2</priority>
        <properties>
            <property name="xpath" value="//MarkerAnnotation/Name[@Image = 'Enumerated']" />
        </properties>
    </rule>
</ruleset>
As you see we are using net.sourceforge.pmd.rules.XPathRule as the rule class, and define xpath property for this rule holding our XPath Query. Priority in the above example means: 1 - error, high priority, 2 - error, normal priority, 3 - warning, high priority, 4 - warning, normal priority and 5 - information.

We will add another rule to our JPA ruleset, responsible for reporting a warning when @Enumerated is used with explicit ORDINAL EnumType - it can be either @Enumerated(EnumType.ORDINAL) or @Enumerated(value = EnumType.ORDINAL), therefore we need an alternative of two XPath expressions now:
<rule name="EnumeratedAsOrdinal" message="Enumeration constants shouldn''t be persisted using ordinal." class="net.sourceforge.pmd.rules.XPathRule">
        <priority>4</priority>
        <properties>
            <property name="xpath" value="
                //SingleMemberAnnotation/Name[@Image = 'Enumerated']/following-sibling::MemberValue//Name[@Image = 'EnumType.ORDINAL'] |
                //NormalAnnotation/Name[@Image = 'Enumerated']/following-sibling::MemberValuePairs/MemberValuePair[@Image = 'value']//Name[@Image = 'EnumType.ORDINAL']" />
        </properties>
    </rule>

Now, when we have ruleset holding those two rules, we will import it into Eclipse IDE. At this point I'm assuming that you have already installed PMD plugin for Eclipse (see: PMD - Integrations with IDEs).

Open Eclipse Preferences, find the PMD section and expand it, you should see:


click on "Import rule set ..."


select the file holding the ruleset, choose if you want to import it by reference or copy (in this case your ruleset name will be ignored and 'pmd-eclipse' name will be used), and you should see our two rules added to the list:


Perform the necessary build when asked by eclipse, and before you'll start enjoying our new rules, check the project properties:


"Enable PMD" option should be turned on to let PMD check your code on-the-fly, our newly added rules should be active for this project (they will be by default).

Let's write some "bad code" now, matching the first rule defined by us:


When you point the red marker on the left with your mouse you will see the rule message, as defined in XML:


The second rule matching:


and the message, as defined in XML:



Few links for the dessert:

Sunday, May 29, 2011

EclipseLink - JPA Queries optimization - @JoinFetch, @BatchFetch and Query Hints

@JoinFetch is very helpful when you try to minimize the number of SQL queries standing behind JPA query. I wrote about it in one of my previous posts: JPA Demystified (episode 1) - @OneToMany and @ManyToOne mappings, but it brings also some threats (see JPA - insert instead of update). This post will describe one of them, related to limiting number of results returned by JPA query.

Let's use same entities as in JPA Demystified (episode 1) - @OneToMany and @ManyToOne mappings. We have Employer:
@Entity
@Table(name = "EMPLOYERS")
public class Employer implements Serializable {
    ...
    private List<Employee> employees = new ArrayList<Employee>();
    ...
    @OneToMany(mappedBy = "employer", cascade = CascadeType.ALL)
    @JoinFetch(JoinFetchType.OUTER)
    public List getEmployees() {
        return employees; 
    }
    ...
}
and Employee:
@Entity
@Table(name = "EMPLOYEES")
public class Employee implements Serializable {
    ...
    private Employer employer;
    ...
    @ManyToOne(optional = false)
    @JoinColumn(name = "EMPLOYER_ID")
    @JoinFetch(JoinFetchType.INNER)
    public Employer getEmployer() {
        return employer;
    }
    ...
}
As you see, nothing special, well maybe except the @JoinFetch annotation on employees property of Employer.

We will use the query fetching only few employers from the DB:
    ...
    @PersistenceContext
    private EntityManager entityManager;
    ...
    TypedQuery<Employer> query = entityManager.createQuery("select e from Employer e", Employer.class);
    query.setMaxResults(5);    
    List<Employer> employers = query.getResultList();
    Assert.assertEquals(5, employers.size());    
    employers.get(0).getEmployees().get(0);
    ...
Suppose that we have 8 employers in the database, each of them have 5 employees. When you run the above code you'll receive: java.lang.AssertionError: expected:<5> but was:<1>. Why?

The truth is hidden in the dark ;) - JPA query will produce following SQL (target DB is MySQL):
SELECT 
    t1.ID AS a1, t1.BUSINESS_NAME AS a2, 
    t0.ID AS a3, t0.FIRST_NAME AS a4, t0.EMPLOYER_ID AS a5 
FROM EMPLOYERS t1 
    LEFT OUTER JOIN EMPLOYEES t0 ON (t0.EMPLOYER_ID = t1.ID) 
LIMIT 0, 5
As you see, @JoinFetch annotation forced EclipseLink to fetch employers and employees in one SQL query, but limiting number of records is performed the same way as for fetching the employers only, and therefore the result set will be limited to: Employer 1 - Employee 1, Employer 1 - Employee 2, ... , Employer 1 - Employee 5. This result set will be in turn converted by EclipseLink to one employer with 5 employees attached, and the result of the query will be 1 Employer, instead of expected 5.

Good Lord! Is there any hope for the people looking for some queries optimization?! - Of course my dear Watson :) - we can always replace one EclipseLink specific annotation (@JoinFetch) with another (@BatchFetch) or the JPA Query hints ...

Let's focus on the @BatchFetch annotation first. We will modify the Employer entity in the following way:
...
    @OneToMany(mappedBy = "employer", cascade = CascadeType.ALL)
    @BatchFetch(BatchFetchType.JOIN)
    public List<Employee> getEmployees() {
        return employees;
    }
    ...
The @BatchFetch annotation tells EclipseLink to fetch all related objects in one query, so instead of one query (when using @JoinFetch) we will have two (one for fetching employers, and second one for fetching the related employees). As you probably suppose, our code will work correctly this time, at least on the Java level ;) - because when we check the generated SQL, we will see:
SELECT ID AS a1, BUSINESS_NAME AS a2 FROM EMPLOYERS LIMIT 0, 5

SELECT t1.ID, t1.FIRST_NAME, t1.EMPLOYER_ID, t0.ID, t0.BUSINESS_NAME 
FROM EMPLOYERS t0, EMPLOYERS t2, EMPLOYEES t1 
WHERE ((t1.EMPLOYER_ID = t2.ID) AND (t0.ID = t1.EMPLOYER_ID))
As you see it's not the optimal choice - we fetch only 5 employers and ALL employees, from which only those who are bound to one of our 5 employers are used. Waste of DB and network resources :(

When you try EXISTS type of @BatchFetch the queries looks like this:
SELECT ID AS a1, BUSINESS_NAME AS a2 FROM EMPLOYERS LIMIT 0, 5

SELECT t1.ID, t1.FIRST_NAME, t1.EMPLOYER_ID, t0.ID, t0.BUSINESS_NAME 
FROM EMPLOYERS t0, EMPLOYEES t1 
WHERE (
    EXISTS (
        SELECT t2.ID FROM EMPLOYERS t2 
        WHERE (t1.EMPLOYER_ID = t2.ID)
    ) AND (t0.ID = t1.EMPLOYER_ID)
)
Still not the optimal choice, same as the above we fetch 5 employers and ALL employees :(

Only the IN type produces the SQL, which can be useful for us:
SELECT ID AS a1, BUSINESS_NAME AS a2 FROM EMPLOYERS LIMIT 0, 5

SELECT t1.ID, t1.FIRST_NAME, t1.EMPLOYER_ID, t0.ID, t0.BUSINESS_NAME 
FROM EMPLOYERS t0, EMPLOYEES t1 
WHERE ((t1.EMPLOYER_ID IN (1, 2, 3, 4, 5)) AND (t0.ID = t1.EMPLOYER_ID))
As you see @BatchFetch annotation give us possibility to fetch exactly 5 employers, and limit the number of required SQL queries to 2. There is one potential problem with IN type usage, which is related to limit in number of expressions for SQL IN clause for some databases (ex. Oracle - max 1000 expressions).

If you prefer, for some reason, to control the employees fetching on per-query basis, you have to switch from the annotations usage to Query Hints, for ex.
query.setHint(QueryHints.BATCH, "e.employees");
query.setHint(QueryHints.BATCH_TYPE, BatchFetchType.IN);
Few lectures for the dessert:

Wednesday, May 4, 2011

@OneToOne with shared primary key

A Friend of mine asked me lately how would I define @OneToOne mapping in JPA with shared primary key. Well, we will definitely need an example ;) - Suppose that we have two entities: Primus and Secundus. Both entities have primary key using Long Java type. They are related 1-1, and Secundus should use the same primary key as Primus. Let's start with following state of Primus:
@Entity
@Table(name = "PRIMUS")
public class Primus {

    private Long id;
    private String name;
    private Secundus secundus;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @OneToOne(cascade = CascadeType.PERSIST, mappedBy = "primus")
    public Secundus getSecundus() {
        return secundus;
    }
...
}
Primus is more important from our point of view, it should be persisted first, and then Secundus, therefore we define the relation between them using mappedBy attribute. We also use cascading here to be able to persist both entities at once. Note, that we will only try to persist the entities, that's why there is only one type of cascade.

Let's take a look at Secundus now:
@Entity
@Table(name = "SECUNDUS")
public class Secundus {

    private Long id;
    private String name;
    private Primus primus;

    @Id
    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @OneToOne
    @PrimaryKeyJoinColumn
    public Primus getPrimus() {
        return primus;
    }
...
}
Note, that we don't define the method of generating Secundus identifier here. We also use Secundus identifier (primary key) as the join column for the primus property (see @PrimaryKeyJoinColumn).

Let's try to test the persisting of those two with following code:
 ... 
    @PersistenceContext
    private EntityManager entityManager;

    @Test
    @Transactional(readOnly = false)
    public void test01() {
        final Primus primus = new Primus();
        final Secundus secundus = new Secundus();
        primus.setSecundus(secundus);
        entityManager.persist(primus);
    }
...
The above code and our current JPA mappings will lead to the following SQL queries (used database is MySQL 5.5):
INSERT INTO PRIMUS (NAME) VALUES (null)
SELECT LAST_INSERT_ID()
INSERT INTO SECUNDUS (ID, NAME) VALUES (null, null)
and of course fail at the second insert.

As you probably suppose the Primus identifier is set right after the select last_insert_id() query is performed, let's try to use this knowledge to initialize the Secundus identifier - we will modify the Primus method setId as visible below:
    public void setId(Long id) {
        this.id = id;
        if (null != secundus) {
            secundus.setId(id);
        }
    }
This time the queries looks good:
INSERT INTO PRIMUS (NAME) VALUES (null)
SELECT LAST_INSERT_ID()
INSERT INTO SECUNDUS (ID, NAME) VALUES (12, null)
and both entities are written into database :).

At this point I would consider one more modification of Primus - which is not required for entities persisting, but will assure that both entities are bound in proper way:
    public void setSecundus(Secundus secundus) {
        this.secundus = secundus;
        if (null != secundus) {
            secundus.setPrimus(this);
        }
    }

I'm curious if you have any other solution for this situation, feel free to share it with me :)

PS: The above solution does work for following JPA providers: EclipseLink (2.1) or Hibernate (3.4), but doesn't work for OpenJPA (2.1).



For JPA 2.0+ based solution see my post: @OneToOne with shared primary key, revisited :)

Sunday, April 10, 2011

JPA and unmodifiable collections

Patrycja Węgrzynowicz (see Yon Labs / Yon Consulting) had very interesting talk on 33rd Degree Conference this year called "Patterns and Anti-Patterns in Hibernate". Inspired by this talk, I decided to verify JPA providers behavior regarding unmodifiable Collections.

I will use the same Employer - Employee - Benefit model as in my previous JPA posts (ex. JPA Demystified (episode 1) - @OneToMany and @ManyToOne mappings).

Let's take a look at the Employer entity:
@Entity
@Table(name = "EMPLOYERS")
public class Employer implements Serializable {
    ...
    private List<Employee> employees = new ArrayList<Employee>();
    ...

    public void addEmployee(Employee employee) {
        employee.setEmployer(this);
        employees.add(employee);
    }
    ...
    @OneToMany(mappedBy = "employer", cascade = CascadeType.PERSIST)
    public List<Employee> getEmployees() {
        return Collections.unmodifiableList(employees);
    }
    ...
    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }
    ...
}
As you see addEmployee and getEmployees method usage should protect the employees list from the modifying outside the Employer.

Let's use following test:
    @Test
    @Transactional(readOnly = false)
    public void test03() throws Exception {
        Employer employer = employerDAO.get(1L);
        assertEquals(3, employer.getEmployees().size());
        employerDAO.merge(employer);
    }
Nothing special, we fetch the Employer from database, doesn't change anything, and try to merge the state into database. Simple, isn't it? Well, when you try to use Hibernate as JPA provider you'll encounter:
java.lang.UnsupportedOperationException
 at java.util.Collections$UnmodifiableCollection.clear(Collections.java:1037)
 at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:501)
 at org.hibernate.type.CollectionType.replace(CollectionType.java:574)
 at org.hibernate.type.TypeFactory.replace(TypeFactory.java:505)
 at org.hibernate.event.def.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:392)
 at org.hibernate.event.def.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:200)
 at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:173)
 at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:81)
 at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:704)
 at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:688)
 at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:692)
 at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:235)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
 at $Proxy29.merge(Unknown Source)
 at [...].dao.jpa.DefaultEmployerDAO.merge(DefaultEmployerDAO.java:22)
 at [...].dao.EmployerDAOTest.test03(EmployerDAOTest.java:76) 
Good Lord, why it is trying to clear the collection!? Patrycja mentioned in her talk, that when you return the unmodifiable view of collection, Hibernate will treat the property as "dirty" (because both collections are different as objects) and try to persist the changes - which in this case means deleting all collection elements and persist same collection elements again!! ...

OK, maybe OpenJPA will behave better ...
java.lang.IllegalAccessError: class org.apache.openjpa.util.java$util$Collections$UnmodifiableRandomAccessList$0$proxy cannot access its superclass java.util.Collections$UnmodifiableRandomAccessList
 at java.lang.ClassLoader.defineClass1(Native Method)
 at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:466)
 at serp.bytecode.BCClassLoader.findClass(BCClassLoader.java:50)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
 at java.lang.Class.forName0(Native Method)
 at java.lang.Class.forName(Class.java:247)
 at org.apache.openjpa.util.GeneratedClasses.loadBCClass(GeneratedClasses.java:67)
 at org.apache.openjpa.util.ProxyManagerImpl.getFactoryProxyCollection(ProxyManagerImpl.java:363)
 at org.apache.openjpa.util.ProxyManagerImpl.newCollectionProxy(ProxyManagerImpl.java:189)
 at org.apache.openjpa.kernel.StateManagerImpl.newFieldProxy(StateManagerImpl.java:1824)
 at org.apache.openjpa.kernel.StateManagerImpl.newProxy(StateManagerImpl.java:1790)
 at org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:543)
 at org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:934)
 at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:691)
 at org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:117)
 at org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
 at org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3047)
 at org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3121)
 at org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
 at org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
 at org.apache.openjpa.enhance.RedefinitionHelper.accessingField(RedefinitionHelper.java:59)
 at org.apache.openjpa.enhance.[...]$entities$domain$Employer$pcsubclass.getEmployees(Unknown Source)
 at [...].dao.EmployerDAOTest.test03(EmployerDAOTest.java:75)
Nope :(. OpenJPA fails much sooner - it is unable to fetch the Employees list!

Our last hope - EclipseLink ... Works :) it performs appropriate selects, to fetch the entity, then on merge verifies that there were no changes in it, and simply does nothing.

Of course all those 3 providers work perfectly when you simply return the collection, not the unmodifiable view.

Saturday, April 2, 2011

NSObject - description method

I believe that all Java Developers, using debugger from time to time, are appreciating toString method in Object class :) - probably the same feelings share all Objective-C Developers who know NSObject's description method.

In short, this method returns a string that represents the content of the receiving class, by default it is something like this:
<Card: 0x4b64c90>
Sounds mysterious for now, but when you override this method in your class (Card in this example), and make it look like this (face and value are properties of Card class):
- (NSString *) description {
    return [NSString stringWithFormat: @"face: %@, value: %d", self.face, self.value];
}
And then, in debugger, select Print / Description on the Card object:


You will see something like that:


The same method is used while you send the messages to the system log, using NSLog function:
NSLog(@"Card: %@", card);
Similar to the debugger Print / Description command, you'll see your object description in console when the NSLog will be reached in code.

Monday, March 21, 2011

Useless Flow Managed Persistence

Spring Webflow has some interesting feature called Flow Managed Persistence. In short: it allows you to change some persistent entity during the flow, and merge the state of entity into persistence context at the end of the flow.

Sounds interesting, and is worth trying for sure :) - but you have to be aware, that Spring Webflow guys have overlooked something very important. The JpaFlowExecutionListener, which is involved in the Flow Managed Persistence handling, binds an Entity Manager instance to the flow scope, when a flow execution starts.

So what? - you may say :) - hm, let's look at the Spring Webflow documentation: "any objects stored in flow scope need to be Serializable" - and now back to the Entity Manager interface - nope - it doesn't extend Serializable, so we have no guarantee that it will be.

Indeed when you use the EclipseLink as JPA provider you'll get beautiful "SnapshotCreationException: Could not serialize flow execution; make sure all objects stored in flow or flash scope are serializable".

I've reported this problem in Spring Webflow JIRA - see JpaFlowExecutionListener shouldn't assume that EntityManager is Serializable

You may also find this problem in Community Forum - EclipseLink, Toplink NotSerializableException - mentioned first on August 28th, 2008.

I'm waiting eagerly for the fix :)

Saturday, March 5, 2011

Spring @Autowired, JUnit and Mockito

Few days ago I've encountered interesting problem with autowiring Mockito based Spring Framework beans, let me share it with you :)

Everything started when I've made JUnit test for some business logic code.
...
import static junit.framework.Assert.assertNotNull;
...
@ContextConfiguration({ "classpath:.../business-logic.xml", "classpath:.../orm-jpa.xml",
"classpath:.../test/mockito.xml", ... })
public class MockitoTest extends AbstractJUnit4SpringContextTests {

    @Autowired
    private EmployeeManager employeeManager;

    @Test
    public void test01() {
        assertNotNull(employeeManager.get(Long.valueOf(1L)));
    }
}
Default EmployeeManager implementation used by me delegates the entity fetching to EmployeeDAO:
@Component("business-logic.EmployeeManager")
public class DefaultEmployeeManager implements EmployeeManager {

    @Autowired
    private EmployeeDAO employeeDAO;

    public Employee get(Long identifier) {
        return employeeDAO.get(identifier);
    }
}
EmployeeDAO in this example is a mock created using Mockito:
<bean id="persistence.EmployeeDAO" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="....dao.EmployeeDAO" />
</bean>
When I tried to run the test, it responded with beautiful exception:
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'business-logic.EmployeeManager': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ... .dao.EmployeeDAO ... .logic.impl.DefaultEmployeeManager.employeeDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [... .dao.EmployeeDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
...
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ... .dao.EmployeeDAO ... .logic.impl.DefaultEmployeeManager.employeeDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [... .dao.EmployeeDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. 
My first thoughts were - Why the heck it doesn't work?! There is a bean which can be used for autowiring! - but after few seconds I realized that I'm wrong :) - Here is the explanation why ;)

When Spring Framework creates the beans, and tries to autowire the EmployeeManager properties it seeks for the bean having class EmployeeDAO, but at this point our Mockito based bean is still a Factory, not concrete instance, therefore Spring Framework checks the mock method of our Factory, to determine the type of returned objects. As you may see below it has signature:
public static <T> T mock(Class<T> classToMock)
and thus the determined type is Object, which of course doesn't match the desired one (EmployeeDAO).

Let me read your mind at this point ;) - You think: What can we do with it? - Well, we have to assure that EmployeeDAO bean will be turned into real instance before it will be requested for autowiring.
In other words EmployeeDAO bean should be defined BEFORE the beans using it for autowiring.

We can do it in following ways:
  1. Change the @ContextConfiguration annotation to move the file defining this bean (mockito.xml) in front of all others (very naive solution, but sometimes sufficient ;) )
  2. Define for all beans referring EmployeeDAO that they depend on it
The last one can be achieved in following way:
@Component("business-logic.EmployeeManager")
@DependsOn("persistence.EmployeeDAO")
public class DefaultEmployeeManager implements EmployeeManager ...
when you define your beans using context scanning, or if you simple define them in XML, using depends-on attribute of the bean.

PS: Libraries/Frameworks used in the above example: Spring Framework - 3.0.4, Mockito - 1.8.5 and JUnit 4.8.1

Sunday, February 20, 2011

Test me to the end of code

Those who know me may think I'm Javaholic - well, maybe a little ;) - but I do like other programming languages too :) - really :) - below you may find results of my small experiment with XCode 4, Objective-C categories and Unit Tests.

I've started with the idea of extending NSArray class with method returning an array with shuffled elements, which can be achieved using Objective-C categories [1], in following way:

Define the Shuffling category (NSArray+Shuffling.h):
#import <Foundation/Foundation.h>

@interface NSArray (Shuffling)

- (NSArray *) shuffle;

@end
Implement the category using modern version of Fisher-Yates shuffle algorithm [2] (NSArray+Shuffling.m):
#import "NSArray+Shuffling.h"

@implementation NSArray (Shuffling)

- (NSArray *) shuffle 
{
    NSMutableArray *result = [self mutableCopy];
    int j = 0;
    for (int i = [result count]; i >= 1; i--) {
        j = arc4random() % i;
        [result exchangeObjectAtIndex:j withObjectAtIndex:i-1];
    } 
    return [[result copy] autorelease];
}

@end

We have the code, let's put it into some project where we could test it - static library will be enough for our needs, let's use it:


XCode 4 let you select if you will use Unit Tests for the project when you define its name:


After creating new project, we will add our source code to it:


It will be new Objective-C Category:


based on NSArray:


and bound to the primary project target:


Now we can put the source code described at the beginning of this post into newly created files.

Project created the above way with XCode 4 has automatically generated Unit Test, which can be run at this point to check if everything works correctly - before you do it, check if you selected the iPhone Simulator for running it - it cannot be done on physical device.

Let's run the XCode 4 generated Unit Test:


What we will see at this point will be:


It looks like everything is fine till now :) - let's create our own test instead of STFail macro:
- (void)testExample 
{
    NSArray *array = [NSArray arrayWithObjects: [NSNumber numberWithInt:1], [NSNumber numberWithInt:2], [NSNumber numberWithInt:3], [NSNumber numberWithInt:4], [NSNumber numberWithInt:5], [NSNumber numberWithInt:6], [NSNumber numberWithInt:7], [NSNumber numberWithInt:8], nil];
    NSArray *shuffledArray = [array shuffle];
    STAssertNotNil(shuffledArray, @"Shuffled array is nil");
    STAssertTrue([shuffledArray retainCount] == 1, @"Retain count: %i", [shuffledArray retainCount]);
    NSLog(@"Shuffled: %@", shuffledArray);
}

When you run it this time you'll get the exception:


because our static library was not used by the linker, and thus our NSArray extension is not visible, let's correct it by adding appropriate linker flag [3] (-all_load):


When you run the test now you should receive something like this:


As you see this time Unit Test is working correctly, and our shuffling code too :)

Few links for the dessert:
  1. Objective-C: Categories
  2. Fisher–Yates shuffle
  3. Objective-C Category Causing unrecognized selector
  4. Test Driving Your Code with OCUnit
  5. OCUnit: Integrated Unit Testing In Xcode

Sunday, January 30, 2011

STS - @RequestMappings View

Sometimes I wonder if I really know the tools lurking beneath the surface of my Eclipse IDE ;) - today I've discovered @RequestMappings View - part of SpringSource Tool Suite (STS). I know, you probably use it for centuries already ;) - but for me it was really nice surprise :) - The rest of this post is for all the developers having feeling that there should be something like that, but still looking for it ;)

Let's start from the beginning, and open this View:


At the bottom of the Eclipse window you should see something like this:


Let's populate it with some data now ;) - this is the hardest part, because your project should have a Spring Project Nature, my own didn't have it, therefore I had to correct its configuration - adding missing Nature first:


and defining which files contain Spring Beans:


Finally we can find the file defining our application's request handlers, and populate the View with defined mappings:


Which will look somehow like this now:


When you click twice on any of the lines in this view you'll be transfered to the appropriate handler method, like in this example:


I'm still learning this View, and hope that next STS versions (I'm using 2.5.2 currently) will bring more functionality in it.

Saturday, January 29, 2011

jQuery Templates and JSON

Imagine the Web Application executing some functionality on the server using AJAX and processing data returned in JSON format. Very often such a processing is also updating UI with the provided data - recently we gained a powerful ally in this task - jQuery Templates.

This post will give you quick example of using jQuery Templates. We will focus on the client side of this process, assuming that the JSON response will look like this:
{"employer":{"id":1,"employees":[{"id":1,"firstName":"John","benefits":[{"name":"Healthy Employees","id":1,"type":"HEALTH_COVERAGE","startDate":1104534000000,"endDate":null},{"name":"Gold Autumn","id":2,"type":"RETIREMENT_PLAN","startDate":1104534000000,"endDate":null},{"name":"Always Secured","id":3,"type":"GROUP_TERM_LIFE","startDate":1104534000000,"endDate":null}]},{"id":2,"firstName":"Mary","benefits":[]},{"id":3,"firstName":"Eugene","benefits":[]}],"businessName":"Mighty Ducks"}}
And here comes the HTML/JavaScript part:
<html>
    <head>
    ...
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
        <script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
        <script type="text/javascript">
        $(document).ready(
            function() {
                $("#ajax-trigger").click(
                    function(event) {
                        event.preventDefault();
                        $.getJSON("templates.json", { 'employerId' : 1}, 
                            function(data) {
                                $("#employerList").tmpl(data).appendTo("#ajax-target");
                            });
                    });
            });
        </script>
        <script id="employerList" type="text/x-jquery-tmpl">            
            {{tmpl(employer) "#employerTemplate"}}
        </script>
        <script id="employerTemplate" type="text/x-jquery-tmpl">
            <h1>${businessName}</h1>
            <table>
                <caption>Employees</caption>
                {{each(i, employee) employees}}{{tmpl(employee) "#employeeTemplate"}}{{/each}}
            </table>
        </script>
        <script id="employeeTemplate" type="text/x-jquery-tmpl">
            <tr>
                <td>${firstName}</td>
            </tr>        
        </script>    
    </head>
    <body>
        <div>
            <a href="javacsript:void();" id="ajax-trigger">AJAX</a>
        </div>
        <div id="ajax-target"></div>               
    </body>
</html>
As you see the whole machinery is triggered when you click on the "AJAX" link, then JSON response is fetched from server using $.getJSON and processed using following code:

$("#employerList").tmpl(data).appendTo("#ajax-target");

Which in more human friendly language means - find the element having id employerList and render its content as template using data returned from server, then append the result to element having id ajax-target.
Our first template (employerList) extracts the employer information from the provided data, and calls another template for this specific employer:

{{tmpl(employer) "#employerTemplate"}}

The employer template in turn displays the employer's business name, and for each of its employees calls the last template we use in this example - employeeTemplate

<h1>${businessName}</h1>
<table>
    <caption>Employees</caption>
    {{each(i, employee) employees}}{{tmpl(employee) "#employeeTemplate"}}{{/each}}
</table>

The employee template is very simple in this example, it only displays employee's first name

<tr>
    <td>${firstName}</td>
</tr>

Let's take a look at the above code in action - first the page right after loading:
Nothing special, except the big white space ;) - now after processing the JSON response:
As you see it works :) - and it's pretty fast, this very simple template was rendered on my chrome browser in less than 3 ms.

One and only doubt related to this solution which is troubling me is its compliance with HTML standard, because we put here different html tags inside of script tag - and W3C validator is not happy with that ;) - the question is if we should ...

Few links for the dessert:
  1. jQuery API - Templates
  2. Introducing jQuery Templates 1: First Steps
  3. jQuery Templates is now an Official jQuery Plugin
  4. jQuery JavaScript Templates Tutorial: Nesting Templates 

Saturday, January 15, 2011

Spring - Using Beans in HTTP Servlet

So you want to use your beautiful and shining Spring Beans in ugly and ordinary HTTP Servlet? Don't be ashamed ;) Sometimes we all have to do it, and we do it in many different ways ;) Below you may find few examples.

Old-fashioned way :) - used by me till some beautiful Thursday morning ...
public class BeanTest extends HttpServlet {

    private EmployerManager employerManager;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Do something amazing with the Spring Bean ...
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext());
        employerManager = applicationContext.getBean("business-logic.EmployerManager", EmployerManager.class);
        super.init(config);
    }

}
As you see, you can access Spring WebApplicationContext and then the desired bean by its identifier. Main disadvantage of this method is the bean identifier hardcoded into Servlet code. Especially if you are performing automatic component scan in Spring (ex. <context:component-scan base-package="[...].logic.impl" />). In this case you have two choices:
  1. Define the identifier of the bean using annotations:
    
    @Service("business-logic.EmployerManager")
    public class DefaultEmployerManager implements EmployerManager {
       ...
    }
    
  2. Use default bean identifier created by Spring in your Servlet - see: Naming autodetected components
Now relax, close your eyes, think about the refactoring the code, and all those hardcoded names which you should change by hand. It's time to forget this method my Friend, as I did. :)

Thankfully there are many young people, with open mind, who don't use the old-fashioned ways of doing things, and invent their own, as did my colleague - Bartek. Below you may find method doing the same as the above one, but based on @Autowired annotation usage.
public class BeanTest extends HttpServlet {

    @Autowired
    private EmployerManager employerManager;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Do something amazing with the Spring Bean ...
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext());
        super.init(config);
    }

}

SpringBeanAutowiringSupport will inject the appropriate Spring Beans into all your Servlet's properties marked with @Autowired annotation. That's all :) No hardcoding of bean names, no worries about future refactorings. Now relax, close your eyes, ...

Sunday, January 9, 2011

Spring MVC - Session Attributes handling

Spring Framework 2.5 has introduced annotation based programming model for MVC Controllers. Spring Framework 3 has made next step, and deprecated widely used SimpleFormController. Now we are all doomed to use annotations ;) but do we really understand what is going on behind the scenes?

Let's take a look at the @SessionAttributes and SessionStatus today :) If you are not familiar with them, you should start with Specifying attributes to store in a session with @SessionAttributes and Supported handler method arguments and return types before you will continue reading this post.

@SessionAttributes annotation is used on the Controller class level to declare used session attributes. All Model attributes having names or types defined in this annotation will be automatically persisted and restored between the subsequent requests. Sounds easy and beautiful, isn't it? Small declaration instead of boring HttpSession's getAttribute / setAttribute calls. Tempting :), try it and you'll find it can be dangerous too ...

"Automatically persisted" should alarm you :) - where? how? when? and for how long? - you should ask immediately :) - Well, let's take a deeper look at it :)

Strategy used for persisting Model attributes is defined by SessionAttributeStore implementation, Spring Framework by default uses DefaultSessionAttributeStore which in turn relies on HttpSession as the storage (for Servlet environment). You can provide custom implementation of the SessionAttributeStore interface, which you then enable by supplying a custom bean configuration for an AnnotationMethodHandlerAdapter (see Spring MVC pitfall - overriding default beans).

Model attributes are persisted at the end of request handling by AnnotationMethodHandlerAdapter, after calling your handler method responsible for request handling and after determining the ModelAndView for the response. Their names in Model are used as their names in the persistent storage, ex. @SessionAttributes("form") will trigger persisting Model attribute named "form" as HttpSession attribute named "form".

Persisted Model attributes will be removed only if you'll call SessionStatus.setComplete() method in some of your handler methods.

If at this point you still don't have any doubts, let me share my own with you:
  1. Cleaning not needed session attributes is a little tricky, because in a little more complicated applications users usually have possibilities to use Breadcrumb Navigation, some Menus, etc., each of them can cause switching the flow from one to another without calling SessionStatus.setComplete() method (and thus without cleaning the attributes used by the flow). 
  2. Using default SessionAttributeStore implementation and same names for Model attributes for different types of data will sooner or later lead to beautiful ClassCastException. Why? Because when some part of your application will persist attribute of class A under name "form", and user will then switch without cleaning it to other functionality, using also "form" attribute, but expecting it to be of class B, that will not end with the exception only if A extends B.
We all struggle with the HttpSession attributes cleaning, even not using Spring Framework, in fact. Both the problems mentioned by me above can be found outside the Spring Framework based application too. Using this beautiful and shining @SessionAttributes annotation you have to know how does it work, otherwise it will make you mad, instead of helping you.

For the dessert :) - few pitfalls you may encounter while using @SessionAttributes:
  1. When you refer to non-existing session attribute using @ModelAttribute annotation, HttpSessionRequiredException will be raised, like in following example:
    @SessionAttributes("abc")
    public class MyController {
    
        @RequestMapping(method = RequestMethod.GET)
        public void onGet(@ModelAttribute("abc") String something) {
            ...
        }
    }
    
    This exception, like the any other, can be then handled by you, using @ExceptionHandler annotation for example.
  2. SessionStatus.setComplete() method will trigger cleaning of Session Attributes, but only those which Spring will find "actual session attribute". Suppose that you declare 3 session attributes, but use only 1 of them in your handler method parameters, like in following example:
    @SessionAttributes({ "abc", "def", "ghi" })
    public class BindingTestController {
    
        @ModelAttribute("abc")
        public String createABC() {
            return "abc";
        }
    
        @RequestMapping(method = RequestMethod.GET)
        public void onGet(@ModelAttribute("abc") String something) {
            // do nothing :)
        }
    
        @RequestMapping(method = RequestMethod.POST)
        public void onPost(@ModelAttribute("abc") String something, BindingResult bindingResult, SessionStatus sessionStatus) {
            sessionStatus.setComplete();
        }
    
    }
    
    Only the "abc" attribute will be considered as "actual session attribute", and removed on POST request.
  3. Attribute will be flagged as "actual session attribute" while resolving @ModelAttribute annotated method parameters and AFTER request processing - in this case all Model attributes are checked if they should be persisted (according to @SessionAttributes annotation). 
  4. Assuming that you pass the parameter to some flow, using @SessionAttributes mechanism may lead to surprises, sometimes unpleasant :( Suppose that you want to start new flow programmatically, from Controller A, you put the flow parameter on session, under name "parameter", and mark the Controller B (handling the entry point to the flow) with the @SessionAttribute("parameter"). That will not work my Friend, "parameter" will not be restored into B Controller's Model on entry, because it is not an "actual session attribute" (see above), at least before the first request handling. (Spring 3.1 brings remedy for this problem, named Flash Attributes - see my post Spring MVC - Flash Attributes)