Sunday, August 17, 2014

TDD - Test Driven Development

Intro:


One method for coding stable code is TDD.

The basis of TDD is to write the test first, test it (and get an obvious fail) and then write the implementation.

Why would you do it this way?

First:
Because you implement the classes as a request-contract.

Second:
You have value full tests to-go

Third:
With these tests, if you refactor code hopefully your test will alert you for any breakage

My Story:

I started on a project (Java EE 7 with JSF) and wanted to practice junit tests. But for Injected beans and Jsf-contexts, the story got tricky.

Now the Great test framework Arquillian has all the answers for that, BUT some of the things you need is only in alpha state. I struggled with it a lot. So much I actually choose not to do any tests...

BIG MISTAKE!

So when I tried to code a function for deleting a certain thing from the database (in the middle of relations) i got some problems. Every time I changed the code, I had to log in, navigate to the right site, try the function and then try to understand the giant EE stacktrace.

So I did a GIANT Refactoring (actually starting a new project and just copying in the entities).

I tried for 2 days to implement all of Arquillians might for testing actual websites in the server (Graphene, Selenium, Drone). But in the end it didn't work.

But I got the junit tests (run by Arquillian) to work (as injected beans).
So now I could actually test the beans function without all the login and stuff.

And when it's all implemented I can actually do manual Selenium tests to see that it actually works in the website.

A bonus thing is that the test wipes and then populates the database with test-data.
So if I have to drop the database (ex if I change the persistance classes) I don't have to create all the test data manually.

Summary:

So what can we (and especially I) learn from this?

Even if you don't do the tests first like TDD, have a test framework! It saves so much time.

Code ahoy!

Thursday, June 19, 2014

ManagedScheduledExecutorService and Wildfly


So I needed a task to be run once every day. I needed to check if a user had 7 days left of the membership (and mail her/him a notice) and I needed to remove the users and the connected stuff if a members membership had expired.

I thought I would use a cron-job (linux for the win!). But I had made these nice functions with JPQL that retrieved all the users that had the requirements.
I actually stumbled upon the solution quite quickly but boy did it take some annoyance to get it right.

The answer was ManagedScheduledExecutorService. That's a mouthful.
This is a Java EE7 specification so the servers need to implement it to call them selves EE7 Application servers (the web-profile-only servers doesn't count).

With this you can schedule a task (any POJO that implements Runnable which is Java 101).
You can set it to run once, with fixed intervals or fixed delays or you can implement a Trigger (a interface) that sets of at certain times or conditions.

I went for the intervals and Wildfly. Now with Wildfly you can either use the standard config for ManagedScheduledExecutorService or you can config you own. I choose to config my own because the standard one had several threads (4 I think) and I only needed one.

This was done in the config of the server (standalone.xml/domain.xml).
You can also config the threadfactory there.


<managed-scheduled-executor-service name="removerScheduledExectutorService" jndi-name="java:jboss/ee/concurrency/scheduler/RemoverScheduledExectutorService" hung-task-threshold="50000" core-threads="1" keepalive-time="5000" reject-policy="RETRY_ABORT"/>


With the long jndi It actually shows up in the Wildfly server managment interface,

Problems

So I had two problems:

1: My intervals wasn't working at all... For some reason it started 3 threads that ran 3 seconds after each other (I had 15 seconds intervals for testing). And then all 3 threads had 15 second intervals between there own executions. I made it print out the threadId and it was the same for all 3 threads.
So either all threads where doing something weird or I had one thread doing intervals very wrong.

Somehow Netbeans deployment annoyed the server. For when I restarted it without deploying a new version, the services actually kick in right. I also tried to do a classic boolean-switcher from the bean that scheduled the tasks, don't really know if it helped or not. But my intervals was working now.


2: I @Inject my facades to the database (Netbeans Facade-pattern, almost like DAO).
First run worked, but the second run had lost its instance.

So after some masterful reading, googling and swearing I found a soultion, I needed to use the InitailContext and get the @Named bean from there.

yourInstance = InitialContext.doLookup("java:global/YourAPP/YourBean");

And then it was all downhill from there.

I got a lot of experience with Calendar and Date, almost every method in Date is deprecated now, with Calendar as a replacement. So I only use Date as date-instances but for manipulating the date I use Calendar. Go Java 8!


So happy coding! If your having any trouble with a scenario like mine, don't be afraid to ask in the comment-field.


Friday, May 9, 2014

Java EE and Unit testing, Arquillian to the Rescue! Even with Persistence.

As most programmers know, Unit testing is a good practice. You get a quick result if you broke something vital.

And in a simple POJO (Plain Old Java Object) it's not that difficult to make a Unit test, most IDE has JUnit integrated in them.

But what about JavaEE? Now you have a servlet-container, context and persistence to worry about.


There are several solutions for this, the one that I've been focusing on is Arquillian.
Arquillian is a JBoss Community project and development is sponsored by Red Hat, Inc.
http://arquillian.org/

It's a good idé to use Maven with Arquillian. One of the reasons is that you can have different profiles for different servers (glassfish, wildfly, embedded, remote, etc).

My opinions of Maven: http://java-viking.blogspot.com/2014/05/java-ee-maven-and-gradle.html

So Arquillian can simulate JARs or WARs. You can add config-files and classes (or packages).
It can even do persistence.

So i use my Datasource from the server, simulate a War and test it remotely to the server.
The test begins with making a transaction and adding values to the database, I do this with a Facade that Netbeans like to create for JPA Entities.

I've done a test with the findAll-method to see if I get a list with the correct size, and it worked lovely.

So now it's time to test all the important stuff. On my next project I will start with the testing-stuff first now that I know of its capabilities.


So what's next?

Next is to test Arquillian Drone. The Drone-extension is for testing the actual site. So my JSF-sites can actually have automated tests. The newest 2.0.0 (alpha) can even test for mobile.

The Drone can find elements by id and actually do stuff, like login in and testing what the response site is.

So my hours of re-deploying and testing the same thing over and over again feels like a bitter cup of tea right now.

So thats it for now, I have a lot of testing to do. I will also experiment with the managed and embedded server options. But it's always good to have a "remote" server that actually is the same as the release environment,


Comment if you need help with Netbeans, Wildfly and Arquillian, the IDE in the tutorials is Eclipse and uses EclipseLink instead of the Wildfly default (hibernate),

Java EE, Maven and Gradle

So I've been looking a bit at Maven and Gradle.
Gradle is an awesome build tool that have support for the dependencies from maven repositories.

But I have a weak moment, I like the automated stuff in IDEs. And the Gradle-support for Netbeans is not perfect. You can create and open projects, but for a Java EE project, you lose some of the support.

An example is JSF. When you create a normal Web Application in Netbeans, you get automatic support for all the Web technologies it supports. But with Gradle i have to do everything manually.

This is both a good and a bad thing, the good part is to actually learn all the components that are involved, the bad is that it takes time from the coding and frustration while finding the right solution.

Maven, the old and wise, have a different problem. It's problem is that it needs the dependencies declared and downloaded (by maven) while coding.

When you code Java EE against a server, you have the libraries IN the server, the server plugins usually solves this so you don't need to worry about the libraries. They will be provided.
If your using third party libraries, you might need maven? You usually either set the libraries as modules on the server or deploy them separately example Database drivers (JDBC connectors) .


In maven you tell the dependencies to be provided, but you still need them downloaded while coding.
And then comes the kicker, the libraries that the server has, are some times more up to date then those from the maven central repositories!

Even from the same company as the server!

So I'm coding for the Wildfly 8.0 Final, and javax.mail-library isn't in the dependency jboss-javaee-spec. So I had to find it manually and hope that the different version work (1.4.5 in maven, 1.5.1 in wildfly).


So for setting up and starting to code, it's much faster with a IDE and Server-plugin then using Maven.
However!
Maven gives you more structure for different testing and lets face it, many third party libraries are easier to setup via maven. And to automatically do unit-testing in the build face is a plus.

Conclussion:
So I wish that Gradle would be better with Netbeans and I will use Maven for my projects.

Saturday, May 3, 2014

JSF 2.2 FileUpload and a way to get it back

So my Web app needed to be able to upload images for users, "connect" the user and the image and to be able to actually show the image.


Upload:

So JSF 2.2 has a really simple way of doing this. You just put <h:inputFile /> and connect this to a Bean. The type should be "Part" (javax.servlet.http.Part). But to remember is that the <h:form> needs too add enctype="multipart/form-data" as an attribute, <h:form enctype="multipart/form-data">.

Connect:

So now we have a Part in the Bean, but how to save it and where?
Some may want to save the image in the database, this can be done with the BLOB-type. you then have to get the input stream and read it as bytes.

Pros:
All in one place, handled by the DBMS.

Cons:
Database takes much more space
Harder to export all the data for backup-solutions

So what do we do then?
We can save it on the hard drive as regular files. A risk is if the file contains a virus.
How we actually save this is rather easy. The Part-class has a "write"-method which you either can give a relative path or a absolute path. The relative path may put it in the web-applications tmp-folder, it's really the server who controls where its put.

The absolute path makes it easy to do backup scripts to make backups. The big problem is how to reach the files from the web app.

Path:

How to reach files from "above" the web-apps folder is different for the servers. Glassfish has Virtual host/server. Some has context-properties.

The one I have focused on is Wildfly (JBoss Application Server 8).
It was a bit tricky to find the right answer.

But in the config file for your server (domain.conf or one of the standalone confs) there is a subsystem for undertow. Undertow is the new servlet container for JBoss.

In that subsystem there is two parts that's interesting for us right now: Host and Handlers.


In the Handlers part we add
<file name="images-handler" path="your/path/to/save"/>

you can use your servers path-variables

and in the Host part
<location name="/images" handler="images-handler"/>

The handler takes care of where the folder will be retrieved from (read from) and the Host will controll how the web-app will reference it.
In this case you reach it by http://serveradress:port/images

Display:

Now comes the last tricky part. The images-folder is reachable now BUT is reachable by the server-adress WITHOUT the web-apps adress on top of it. You can probably map it to be reachable.

So <graphicImage> gets problems due to it being relative to the web-app.
A simple <img> works great thou.


So either find a way to map it better or use a regular <img>


So that's it for the simple fileUpload of images, especially with Wildfly.

Code ahoy!

Monday, April 14, 2014

JPA: Hibernate Implementation "lazily initialize a collection"

Today I have struggled half a day with a frustrating problem.

I have a ManyToMany-relationship (JPA) with two Entities. Shop and Brand, it's also bidirectional.

Hibernate and Spring-veterans sees where I'm going with this...

If I want to get a Object of Shop from the database, everythings simple. But if I want to get the attribute that's the "ManyToMany" (in this case "Brand") I would get it as a form of Collection.

But here's the kicker: Hibernate has a lazy initialization of these kinds of collections. This is for saving a lot of data loading for every time you get a Shop-object from the database.

I wanted to have a JSF-form with my data and the possibility to update it (specifically the Brands). I wanted to use the selectManyCheckBox component in JSF.

So the Hell began here.

The specific exception I got was (I also got the role-error earlier):
javax.servlet.ServletException: failed to lazily initialize a collection, could not initialize proxy - no Session

You can set the annotation of the ManyToMany to suggest "EARLY" so that it loads all the collection-data with the regular.

And that solution didn't solve my problems. It feels like I almost tried every solution known to man to solve this problem. I did beans that sole purpose was to get the Brands as a list from the Shop and try to merge it with the data in the form and the update-bean.

Of course I tried to google solutions. 95% of the links led me to thinking it was the classic lazy-problem that the Hibernate-session closed before I got my collection data.

But something wasn't right. Because I actually got the data to show in the form correctly quite early. It was the update that caused the problem.

The update was a bean that held the data from the JSF-component, they were connected.
But why did a lazy-error show when it wasn't supposed to load the data but actually update it?

I tried View filter (Open View in Session-pattern), I tried Stateful beans with EXTEND persistance unit.


After half a day I stumble to Hatim Alimam's blog were he had the same problem (but with Primeface implementation).
http://blog.hatemalimam.com/hibernate-lazyinitializationexception-and-pselectcheckboxmenu/

It was a little <f:attribute> that was needed!
If I just put   <f:attribute name="collectionType" value="java.util.ArrayList" /> in the <f:selectManyCheckBox>    Everything worked!

So it wasn't really the classic Lazy-problem, but with that Exception-message, one might think so...

So I hope anyone that has the same problem I had either stumble to this blog or Hatim's.

Cheers!

Sunday, April 13, 2014

Wildfly Injection and JPA: troublesome

So I've been making a Webapplication with classic CRUD via JPA. The database is also used for login-functions. I use JSF with Facelets for View.

JSF can manage beans easily e.g (value="#{myBean.value}")

So I thought that the Bean could be a @Entity. I even have a book that use it like that.
I then Inject the bean in my Facade (a DAO) that should persist it.

I checked so that it had the values that I gave from the View (JSF-form).


But here's the kicker!

I get "java.lang.IllegalArgumentException: Unknown entity: myclass#$Proxy$_$$_WeldClientProxy".

I tried of writing the classes manually in the persistance.xml without any luck.

After a lot of digging, I learned that the Bean that Weld injects (I use Wildfly-server that uses Weld) you doesn't actually get a real instance of your bean. You get a Proxy. So I could get the values, but it was not seen as an Entity.

I confirmed this by making a manual instance of the bean and persisting it with the same Facade-code.

The only difference was the Injection.

So my solution was to make a controller bean which had a manually created field of the bean. And use that bean e.g (value="controllerBean.myBean.value")

The controller bean then used the Facade for persistance.

This solution works for me, the controller bean can then do some validation and more.

Fine and dandy!