Tag Archives: JavaEE

Thoughts on Enterprise

I’ve always considered myself a Spring guy. I mean, it’s so cool to code with Spring! Spring is quite honestly the essence of the modern Java enterprise! It has everything for building an amazing, modern, scalable web application. The most of the routines are highly automated there. Just with few annotations you can convert some crappy POJOa into a real world working webapp. And it will work, it will scale, it will be testable! At some moment it came to a point that it’s not even required to implement some methods. Just annotate a method and Spring will read the method signature and implement the method for you! I believe that in the future you will just write something like:

You may lough, but just go to http://start.spring.io/ and it’s quite near to the idea above. Btw, it will be a cool idea to create a DSL to “talk to Spring”. I always liked and still like coding with Spring!

And then… suddenly, a disaster happened!

I had to start to work on a pure Java EE project! Oh no!

My first reaction was like: well, at least I will be paid for that.

At that period Java EE was considered as something big, outdated, sluggish.. at some parts even retro, with all the negative in this word. And my reaction was predictable since I had some “nice” experience with EJB 2. Yes, yes – EJB 2.0! Remember all this remote interfaces, local interfaces etc, etc. But after that I never touched it again. Good for me!

From several conferences I came to a feeling that Java EE just copies everything from Spring, and renames some of the annotations. And I said to myself – actually, that’s a huge plus for me! I just need to write @Inject instead of @Autowire.

So I’ve started the project and what was my first surprise? Of course it came out of maven. The pom file was really small.

And not more than 3-4 other small dependencies like Primefaces. And that’s ok! You have everything on board. And you don’t have to care about every API you use and every realization of that API etc etc. Unless you want to spoil everything, or, in other words, optimize.

And all of these ugly EJB 2.0 stuff is no more there. Everything is very nice and pure! Again with some annotations you convert your POJOs into beautiful enterprise webapp! Java EE is AWESOME!

So everything is standardized. And that rulez everything. In theory I don’t have to think about on what platform my WAR runs, it should demonstrate the same output every time I call something from my app. Realizing this was like OMG! So now we can develop one app and not think much of what dependencies to include. Take the app and drop it on every server supporting the current profile of Java EE. And we can make almost the same stuff as Spring does. Or I would say the really essential part of it with not so much sugar. Exactly – standards are the true essence of the common functionality widely used in the industry at its best! Damn! I’m in love! From now on I’m a Java EE definite fan! And always will be!

And I have discovered the power of the @EJB annotation!

So I’ve started digging in and then I faced some real life.

The first thing that blocked me was the … you are right – configuration! Every server is configured in its own way!!! So I can’t just drop my app and and make it work, I have to configure some datasources, security and many other stuff. Oh.. so now I have to ship my app with bunch of configs… a little bit disappointing. Still, I don’t have to ship my app with tons of custom libraries, or even with the server itself where it is all set up.

Then some other issues came like one with JAAS. So JBoss/Wildfly and TomEE they both support it but in some slightly different ways.. so in my code I had to put some ifs and see on which platform does the app actually run and call appropriate custom method.

Then the other issue came. The Primefaces upload worked gracefully on TomEE and didn’t even show up on Wildfly. With some insane magic I found out that if I remove the upload filter in web.xml the situation will switch to the opposite – it will work on Wildfly and stop working on TomEE. And that was predictable since at that point they used different versions of Mojarra..

So.. In theory I had to ship different web.xml files. But, that’s so much NOT beautiful! I spent one night almost in tears as I was unable to find a nice solution. But after some beer an in genius solution came to my head – create a server “on start listener” and fix all missing “on the fly”. That was so brilliant that the next night I didn’t sleep as well since I was drunk in the bar. I couldn’t withstand and put some other server depended config there. But that were just two other small things.

And what about the performance and the resources consumption? Surprisingly, the average memory consumption of this app written with Java EE 7. I was expecting something like several gigs, but it was only about 250 Mb RAM on TomEE with about 100 users connected. Not bad at all!!! I have even packed it as single executable jar with TomEE and uploaded on some of the cheap cloud providers. It performed great! Beautiful!

Btw. This app that I’ve written had to make some of Batch activities. And guess what? I didn’t even have to put any additional dependency in my maven or reinvent the wheel, since JBatch was already there in that Java EE provided dependency. I just used it! That’s so cool!

So Java EE can rule them all! In some cases, definitely yes, especially when your tasks are standard enough. And I may say, that from my decade in this branch the most of the tasks are quite standard. With really few deviations.

And what about Spring? With Spring you can do the same and sometimes more (and I wonder if it can do less). Yes, there are some differences in the “philosophy”, but it is obvious that many of the coolest ideas now available in Java EE actually came from Spring, or were deeply influenced by Spring. If there is a request to build something with very narrow Time-To-Market frame, I think I’ll first think about Spring, especially Spring Boot. There I can put some piece of code into real world production within just two hours. Although this can easily be done with TomEE or Payara as well. There are so many things available out of the box, like security, data, MVC, even batches! Batch is one of the examples how a Spring solution inspired the creation of a JSR-352. Btw now it’s the opposite – Spring Batch conforms the standard. It already supports the JBatch job declaration.

So they both do the same? Here is one small thing, rarely discussed. Spring is a proprietor solution. It’s a full ecosystem driven by one company, with a lot of open source efforts included. Still the evolution decision process is a bit different there.

So isn’t Oracle doing the same? I personally think that it has tried to do the same, but they couldn’t. Actually the Java EE standard evolution and support is driven by the Java Community Process. And unlike Spring Java EE is a standard, not a product. At the moment a discussion about Java EE end of life emerged the community and EE vendors started a campaign against those predictions. The well-known Java EE Guardians were formed, with a great support from the community and James Gosling himself. Four big Java EE middleware vendors have even started a common effort for creation of a fraction of the Java EE suitable for optimal microservices operation called Microprofile.io. And its fully community driven and open. The guys standing behind this initiative are really amazing! Truly passionate professionals that do care!

So Spring and Java EE are both comparable and incomparable. And I believe they both serve their needs, although in many areas they are overlapping.

I prefer even not to compare them but there is one thing we developers quite often forget – the financial part of the story. As written in the Adam Bien’s post Spring has its very clear support policy – upgrade or pay for the support. This once played some bad story for us. We have started the project with one version of Spring and somewhere in the middle a new version of it was released with some of the interfaces deprecated. This caused us some delays as we were dealing with updating our code. Still their corporate support is really awesome.

In terms of Java EE, it kind of moves this question to hierarchically lower level – to vendors that do implement this standard has their own support strategies. But the good thing is that they have to correspond to the standard, and the standard does not change too often. On the other side not all the issues can be solved entirely by some standard portable code. At some moment it comes to the point of “no turning away” when it’s necessary to switch to some, for example, underlying API provider specific optimizations. And the portability of the code declines drastically. But you still are not fully tied to one and only proprietor support, and switching it is much less painful. Btw. this question about equalizing of some of the parameters arose at the Microprofile.io multivendor session on the latest Devoxx.

So it’s a tricky question what is better. The answer is though very easy: well, it depends! It’s not always about the technology. A clear knowledge of how your app will perform and evolve can have more impact than just choosing the latest and the trendiest technology.

But if we take the just the technology itself, in my humble opinion Java EE and Spring are doing a great synergy together and move the Enterprise Java forward!

Fetching all the data in JPA?

I’m really not much into blogging recently, but I couldn’t not share this)

ORM is cool. No, it’s really cool! In Java EE that’s the standard for data persisting. It is so cool that by using it people start to forget that there is a database underneath the wonderful and extremely beautiful object model that gracefully expresses the business needs of the app. People don’t have to think about all of this chemistry happening under the curtains. Yes, in RDBMs the data lives in a totally different world, there are absolutely different rules, and the mathematics of it is absolutely different, but who cares! Yes, it is so much automatic! You don’t have to care about the low level ResultSets, mapping the data, their relations, etc etc… And the modern ORMs are so much smart that the data is loaded lazily and only when its need, making the app so much optimized.

And the app works perfectly while it’s been developed. Even when its accepted it works beautiful and as required.

But suddenly something goes wrong. Unexpectedly there are more than one users connected to the app. How could this happen? And the server treacherously crashes with some OutOfMemory exceptions! OMG!

No problem! That can be easily fixed – just by adding some more RAM. For several week its working wonderful. But then the OutOfMemory exception is back! No, that can’t be possible!

That’s the bloody Java EE! It’s very heavy and bad! Should have used Spring instead! Just because it’s cool! Ah.. the app should be rewritten! And of course there is no budget for that!

But still this production issue has to be fixed. And some more RAM is being added jut to keep it alive. Several iterations like that lead back to the same situation. Then, to keep the app running, the cleverest decision is made: a limit of users per time is put on the app. And yay! The scalability problem is solved! Solved, but not exactly, after another period of time the app crashes with the same exception even with one user! 

Common story? I believe that yes. But it’s not much popular to talk about issues like that, since we are all cool programmers, and never make such mistakes.

This story happened to me. But luckily I was not the one to code this app. On my freelance period I was hired as a consultant to solve this issue on a live relatively (not so much) legacy system.

Imagine you have quite an ordinary Java EE webapp, with JSF in front, some business logic expressed with mostly stateless beans and hibernate underneath. Nothing special.

The user logs in and navigates to a certain page which should display a table with some information. One of the columns has links to some downloadable items.

So I’ve logged in, clicked on the required link… and got the error. It was so easy to reproduce the bug. So the first action was to see the Heap Dump with MAT.. and the results were terrifying! A list with several thousand objects having a string field with a several megs of XML inside!!! That’s a WOW!

The JSF itself is designed in the simplest way as well, all the several thousands of items are displayed on one page and the user has to be able to download the XML directly from the object from the table. And you understand it yourself: that’s so wrong! With 10 test items during the development process this approach worked perfectly, and it’s hard to see what it leads to. Yep, for a developer and XML is just a string, which can be a member of an object. What can go wrong…

So imagine the following approximation:

1

Two very easy classes.

Parent:

And Child:

There is a bidirectional OneToMany relation between them:
2

The field names are self-explanatory. Everything which is important, very important and shown has to be visualized in front to the user in the JSF. The other stuff – not on this page.

Looks ok for now… but have you spotted the problem?

Of course its the hugeXMLPayload that should always be loaded, although never displayed…

But, haha, this is so easy to fix! With just few annotations like:

At some point you are right. This should work if the code instrumentation/enhancement is supported and enabled in the JPA persistence provider.

But let’s rethink the way CLOBs and BLOBs are stored. Should this be directly in an object field which is then mapped to some table column? I don’t think that’s a good idea. Big data should be accessed rarely and the access should be really targeted. You may say: but, I have annotated them, and according to StackOverflow the code should be instrumented and, all this data should be loaded lazily. But just annotating them the correct way will not help in Hibernate versions lower then 5, as this code instrumentation was not properly ready yet. As seen, that is just a usual String getter method on an object field, this is not even a relationship which could be expressed with a join underneath.

This didn’t work for us.

So the first quick fix that was applied is naturally dynamic pagination in the JSF table. Thus in memory we had only a small subset of the data. Still loading XML CLOBS in memory every time the page is loaded is a little bit stupid.

What may be the other option effectively NOT to load the entire data? And without changing the data model.. and on a live system? It is not possible to create another “Attachment” object and make a OneToOne relationship to the Child to keep it separated.

So how to make it the most natural and portable way?

The answer I have found in the book “High-Performance Java Persistence” by Vlad Mihalcea. I believe this is an absolutely “A Must Read Book” for every full stack developer.

So the answer to our problem was unexpectedly simple. The first idea was to create a projection and to fetch only the desired fields. But the results of those fetches are arrays with objects. And that’s a little bit raw level approach. There should be something more civilized.

And the civilized approach is called subentities. In JPA it is absolutely legal to map different objects to the same table in the DB. These objects may contain a subset of the data of the original object. And JPA/Hibernate will always fetch only the fields relevant to the object. So we have created a parallel read-only structure with subentities and made just one additional service to serve our JSF.

ParentEntity transformed to ParentEntitySummary:

And the ChildEntity transformed to ChildEntitySummary:

We have just thrown away all unnecessary and left what’s important! So good! If the JPA provider is Hibernate we could add an @Immutable annotation to declare our objects as read-only.

The magic here is in the @Table annotation. Its easy to spot that two classes are actually pointing to the same table in the DB.

For Parent it is:

For Child it is:

And we can absolutely legally to work with them as with all other entities:

So much awesome! And it worked!

This of course is not a silver bullet. I would rather call it a good patching.

So if it is impossible to redesign the DB scheme and have to work with live data, this approach may be a nice escape, especially on a read-only data.

As a result, from 8 GB RAM consumption  we went only to 89 MB on a JBoss machine (server memory footprint included). And its obvious that Java EE is very lightweight and quick!

So the idea of this blog post is to remind that developer is not the only user of the system. And “works on my machine” doesn’t mean it production ready!

And ones again the way the RDBM represents data is different from the way objects do. JPA/Hibernate is awesome tool. It saves great efforts! But its is necessary to make correct decisions on how the data is stored!

Have fun with JPA!