A bit of history and a problem statement of sorts

I’ve been a big fan of criteria queries for writing dynamic JPA
queries for a long time. Sure I could make the same thing happen with a bit of logic and a whole lot of string
concatenation but that gets old really quick. My first experience with criteria queries was with Hibernate 3 so lets
start there and we will follow a query from SQL to JPA 2 Criteria.

We are all probably all most familiar with SQL so lets make that our starting point.

Assuming we have table in the database of tasks lets select those which are assigned to a specific user which have
not been closed.

select * from Task t where t.assignee=1 and t.dateClosed is null

However, we are living in an ORM world though so lets see it in
JPQL
(same syntax in HQL)

Obviously this is more verbose but it also has some readability advantages in my opinion. Even if you disagree with
regard to readability you can see that adding restrictions to the query in a programmatic way is much simpler than with
JPQL/HQL.

However the one thing always bugged with with JPQL/HQL and Hibernate’s Criteria API is that everything is done with strings
and doing things with strings makes refactoring difficult even with good tooling. This is Java and we want something
type-safe.

I will readily admit that upon first taking a look at the JPA 2.0 Criteria API I was really turned off by its verbosity and
complexity. I was turned off so much that I flat out ignored it for the first six months it was available to me. I
still however desired a type-safe way to write my queries so that they would hold up better during refactoring.

Finally I blocked out a day to tinker with the API and see if I could convert a few of my more simple queries. After only a few
minutes I was off and running and haven’t looked back. Here are a couple things I’ve learned during my time tinkering.

The code is longer but I can read and understand it much faster than a JPQL/HQL query.

I can write a criteria query faster due to IDE code completion and not having to review my entity structure to find the name
of that specific column I’m trying to reference.

As the complexity of the query goes up the benefits of the criteria query grow, but you will be forced to do some learning.
I have yet to find a query that I have not been able to convert. The API was very well thought out from this perspective.

My speed of development is faster almost 100% of the time as my criteria queries execute and return the desired results on the
first try. I can’t say the same for my JPQl/HQL which are parsing a potentially very long string with lots of
opportunities for syntax issues.

It isn’t however all sunshine and lollipops

This isn’t to say the API is perfect. It actually fights programmatic creation of queries a little bit. The API is designed
so that the base of your query can reused. For example each time you call the criteriaQuery.where(Predicate... predicates)
it replaces what was previously set. To work around this you need to store your predicates in a separate list and then
add them all at once in array form (varargs). It would be nice if a criteriaQuery.where(List<Predicate> predicates) was
exposed like it is for groupBy and orderBy. Additionally here are some other pain points.

Why is a Fetch<Z,X> not a
Path like
Join<Z,X> is? This means I need to define my "join"
twice it I want it "join fetched". Hopefully this is fixed in JPA 2.1

Metamodel generation is broken in Eclipse. It doesn’t handle the
cyclic nature of the metamodel classes. Thus when I do a project clean I will end up with 20 or so import failed errors.
These are easily resolved by making a meaningless edit to the class to trigger an incremental build but it shouldn’t be this way.

Just do it

Hopefully I’ve inspired you to take another look if you’ve previous dismissed the API as I had. Block out a few hours
and give it a shot. I’ll try to share my utility classes that I’ve written in an upcoming post that have made things a
it easier for me, but in the meantime you really should get down and dirty with the api to understand it fully.

Why would you want to do this?

After years of having my users connect natively to JBoss application servers in production I have had a few little
issues that nagged at me. One of the biggest is that there is not a way to show a custom error page to my users when
the JBoss server is down. Second is that I try and limit as much as I can specific configuration details that go into
the server configuration so that upgrading between minor releases does not require a lot of configuration editing.
Setting up SSL certificates and modifying the default server ports qualifies as hacking up the standard configuration
in my book so that is something I would like to limit/avoid.

The Goal

What we are ultimately trying to do is have an Apache web server handle all the communication between the user and our
system. This communication will be secured via SSL. The apache server however has no real content so it will "proxy"
the requests to our JBoss application server. The application server will be as simple as possible and will not run SSL.

Other details

Our project is named foo

Requests come to https://foo.outjected.com and we don’t want to have our users go to https://foo.outjected.com/foo/
so our web-app context root is going to be "/"

We will redirect you to https://foo.outjected.com if you happen to browse to the non-secure http://foo.outjected.com

We are going to configure the JBoss server with a virtual host so it can support more than one app if needed.

We want to serve our own error page if the JBoss server cannot process our request due to being down.

This little example is going to be using Ubuntu 12.04.1 LTS and JBoss AS 7.1.3.Final but should be compatible with similar setups.

Let’s do it.

I’m going to assume you have a bare bones Apache 2+ server and JBoss AS7 server setup. If you don’t then search around
for some guides. This blog is interested in how to pair them, not the basic setup of each. You should also have a
working application and some basic knowledge of how to deploy on AS7. This isn’t meant to be a soup to nuts guide
for building and deploying your application.

Apache Prep

First create a new directory for our non-proxy (error pages) content /var/www/foo.outjected.com

Go ahead and create a simple error page at /var/www/foo.outjected.com/errors/503.html. This is the page that will be
served if the app server is down.

Run the following commands to enable the needed modules in apache

a2enmod proxy
a2enmod proxy_ajp
a2enmod ssl

Next go into /etc/apache2/sites-available and create a new file foo.outjected.com+. For this example I’m using a
single server so the server I’m proxying to is localhost Your config may/will/should vary.

Where I started banging my head into the table.

This specific issue has actually has jumped up and bit me a few times so I’ll just try explain the most recent one.
Basically I have a new object that I am creating through a JSF form page, and that object needs to have a default
value set at creation which is determined at runtime. For the sake of exposing this little issue lets assume that
this value needs to be used multiple times during the request and thus we will make the producer @RequestScoped
to avoid duplicate database calls.

Where it goes wrong.

What we would expect to happen is the selectOneMenu would initially be selected with the value of our active price book.
However this isn’t going to be the case because the injection of our active price book does not give us an object of
PriceBook.java it gives us an proxy of PriceBook.java and the equals(...) that JSF is going to call
will not return true.

Why it goes wrong.

The CDI EG has determined that there is not meaningful way to implement .equals() and .hashCode() on a proxy that
can delegate to the underlying bean (See OWB-458 &
WELD-695). What this means is that two proxies of the same underlying bean
will be equal. However, two proxies to underlying beans which are equal according to .equals will not be equal.

How can we fix this?

One solution would be to execute the .equals() on the converted value if a converter exists. However, the JSF RI
Mojarra feels (JAVASERVERFACES-2393)
that any proxy must should delegate equals, hashCode and toString to the proxied instance per
java.lang.reflect.Proxy. In the case of CDI the
underlying bean can change during the lifecycle of the proxy and thus delegating isn’t realistic. This appears to be
one of those places where the JSF and CDI expert groups need to step in and find a solution so that developers can
enjoy consistent and predictable behavior in their applications.

A solutions that work now.

By making the bean with the producers @RequestScoped and storing the values in the bean after initial population we
can have default dependent scoped producers which don’t produce proxies and hit the database only once.

Obligatory Links and Compatibility

Whats new?

The main goal of this release was to fill in some gaps in documentation as well as some minor bug fixes which popped up
since the 3.1.0.Final release. I’ve also added in a utility class called
MessageConverter
which allows you to read a MimeMessage back into the internal EmailMessage object used by Seam Mail. This opens up the
option for Seam Mail to receive messages in addition to sending them. Check out
Closed Issues
on the JIRA tracker for details.

What does future look like?

Seam 3 Mail will continue to provide releases in its current format until the time comes for it to transition to
Apache DeltaSpike. In the meantime if you have features for fixes to contribute
just open a JIRA and I’ll be happy to work them in.

How about an example?

POP3+SSL to receive an MimeMessage and convert it. It’s basically for gmail but with values changed to protect the
innocent.

The Problem

One of the more common questions that I see by users coming to "Seam 3 Mail":http://www.seamframework.org/Seam3/MailModule is about sending email asynchronously like was possible in "Seam 2":http://docs.jboss.org/seam/2.2.2.Final/reference/en-US/html_single/#d0e21609. This usually stems from "slowness" problems that arise when sending mail through an interactive application. The problem is that when your "user" submits that order for his fancy new widgets, the confirmation email sent is using the same thread that handled the processing of the web page. Thus the user is left with their browser in a blocked "loading" state thinking your application is slow when in reality it’s the mail server that is taking its sweet time.

The Knee-jerk Reaction

A lot of people will see this blocked thread and think the solution is to fire the email asynchronously. This way the email with be dispatched via separate thread and control will be instantly returned to the user . However the problem with asynchronous methods is that they are fire and forget. If an exception occurs during the send process, then the email is lost and there is no notification that it failed. Realistically, outside of a demo application you generally want some guarantee that the email was, or will be sent as having all those order confirmation emails silently lost will not be pretty.

You Really Want

What is needed is a system which allows you to send email from your application without blocking the execution on the current thread, while at the same time providing a guarantee that the email will be reliably sent (at least from your application to your "SMTP":http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol server).

The Solution

Seam Mail provides a way to replace out the default "send" implementation with one of your own via the "MailTransporter":https://github.com/seam/mail/blob/develop/api/src/main/java/org/jboss/seam/mail/core/MailTransporter.java interface. That way when you call @msg.send()@ you can control how and when the email is "sent". What follows is a basic implementation.

In the code that follows I’m skipping the import statements for the sake of readability, but everything is standard
EE6 + Seam 3 with exception of the Files which comes from Google Guava.

The MailUtility.send(emailMessage, session) sends the email using the configured javax.mail.Session. This is a
blocking implementation and will not release the thread until the destination mail server has acknowledged receipt of
the message. This might take a couple milliseconds or a few minutes depending on message size, server performance and
network bandwidth. If this doesn’t work for you then it’s easy to swap out.

Starting from the top we see that we are injecting a new
Event qualified with @QueuedMail
and typed to MimeMessage. @QueuedMail is a
simple qualifier, and if you have never written one before here is what it looks like.

Next we inject the javax.mail.Session as managed by Seam Mail and implement the
public EmailMessage send(EmailMessage emailMessage) as mandated by the interface. Inside this method we use the Seam
MailUtility class to convert our EmailMessage as built by Seam Mail to a standard MimeMessage and then fire it as a
CDI event.

A CDI event however is still blocking in its execution so lets see what is observing this event.

What we have done here is to receive the CDI event and immediately write the message to persistent storage, in this
case to a queue folder on the application server. Now our thread is returned as fast as we can write the message to
disk. You could also write these bytes out to the database or a in memory store if the loss of queued email during a
server shutdown/crash is not an issue.

All that is needed now is a process to send these stored messages. I’m using a EJB 3.1 scheduled timer, but the options
are endless.

One thing to note is that you have to reset the javax.mail.Session as that is lost when the MimeMessage is converted
to a OutputStream. There is a little added complexity going on here as I like to control the domain part of a
Message-ID, but this is a simple reliable way to handle sending mail in a fast and reliable fashion.