Adam Bien's Weblog

Why Standards Are Hot, Or Why I Still Like Java EE

I started with Java before the advent of EJB, Servlets and Java EE. And it was a huge mess. You had to implement business code agains (too) many, completely different, not even similar application servers. You didn't had any chance to take even a simplistic server side application from one product and install it on another. Some application servers were half "native" and half "pure Java". Also it was absolutely impossible to be knowledgable in more than two products.

The introduction of Servlets, JNDI, EJBs, JMS, JDBC, RMI simplified the development, but the portability still suffered. You could not rely on the availability of a give API on all servers.

The old J2EE brought ...simplicity. With the advent of J2EE in 1999 you knew what you could expect of a certified server. Ironically: J2EE was too simple and incomplete.

For me J2EE and later Java EE brought simplicity and productivity, and I always was puzzled by developers stating "J2EE is too complex" and implementing home-grown infrastructure instead.

In 2014 Java EE 7 is still the most productive, and simple platform:

  1. Java EE is probably the best documented platform. The documentation, specification, samples and even the reference implementation are free and available on the release day.
  2. You "only" have to learn the APIs. All the documentation is free.
  3. The core programming model is based on injection and dependency injection JSR-330 used by many other frameworks in the same way, even the exact same annotations (thanks to Rod Johnson and Bob Lee for this).
  4. You cannot escape JMS, JPA, Servlets sometimes JAX-RS and JCA. Even if you choose a Java EE alternative, you will have to learn these specs. At the same time you can learn Java EE programming model based on Convention over Configuration and Dependency Injection in few minutes.
  5. All modern Java EE Application Servers can be installed in seconds. IDE integration is also very good.
  6. Because the server comes already with all the "plumbing", your WARs are going to be skinny and the turn-around cycles very fast.
  7. The Java EE community is vibrant. JUGs and conference sessions are sold out and Java EE articles are very popular.
  8. After the commercial support for GlassFish was cancelled, many of my clients decided to move to WildFly or TomEE. The "migration" went surprisingly smooth.
  9. I don't have to discuss "best of breeds" technologies or constantly bundle APIs "à la carte". At the very first project day you can start implementing the business logic. Without any initial overhead. Java EE effectively prevents meetings and superfluous discussions.
  10. It is hard to find any other leaner platform. With Java EE you can build either complex applications, or simplistic CRUD use case with the minimal amount of code.
  11. It is good to know, that I'm not alone. Many startups this year chosen Java EE ...because of productivity.

[See also an in-depth discussion in the "Real World Java EE Patterns--Rethinking Best Practices" book (Second Iteration, "Green Book"), page 7 in, chapter "A Brief History of Java EE"]

See you at Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting


NEW workshop: Microservices with Java EE 7 and Java 8, January 26th, 2015, Airport Munich

A book about rethinking Java EE Patterns

Changing Working Directories In Nashorn Scripting

Assigning a directory name to the $ENV.PWD variable: $ENV.PWD="[DIR_NAME]" changes the working directory for the next command:

The ls command will print the contents for directory specified earlier:


#!/usr/bin/jjs -fv
print('Tmp Directory');
$ENV.PWD='/tmp';
$EXEC('ls -al');
print($OUT);
print('Root Directory');
$ENV.PWD='/';
$EXEC('ls -al');
print($OUT);

Thanks to Jim Laskey for the hint

See you at Java EE Workshops at Munich Airport or dedicated / custom virtual workshops!


NEW workshop: Microservices with Java EE 7 and Java 8, January 26th, 2015, Airport Munich

A book about rethinking Java EE Patterns

JUG Tricity, Microservices and The History Repeats

During the sold-out NetBeans day in Munich with Toni Epple and Geertjan Wielenga, we remembered (Geertjan's Report (green dot on a purple line), my coverage) a NetBeans World Tour trip from Poznan to Gdansk in October 2008 with a rent car and with iPhone 1 as a navigation with a poor internet coverage.

Six years later I gave a session Building Reasonable JavaEE 7 Apps on Java8 called “Microservices" for the Tricity Java User Group. It was exactly the same location and I also used NetBeans.

My airplane was supposed to land in Gdansk, but the weather conditions were bad and the airport was closed. We landed in Poznan instead. Buses were supposed to bring us to Gdansk, but no one knew when they will arrive.

After a hard negotiation I took a taxi instead. The taxi driver was very nice and funny. However, he did not knew the route to Gdansk and was afraid to go fast. I used my phone to navigate him to Gdansk and the venue. At the same time I cranked some Java EE code on the back seat and concurrently watched the speed of the car. I reminded the driver to go fast at any attempt to slow down.

As the driver recognized, that >100 attendees are waiting for us in Gdansk, he became really nervous and begun to sweat.

We had a single stop (at a graveyard) to detach the taxi-light at the roof--to go faster.

Via email I kept Kuba Marchwicki informed about the progress. I came one hour later and Kuba delivered a prelude talk to keep the crowd entertained.

I enjoyed the session, got many interesting questions. The event was stopped by the security--they wanted to close venue for the night.

Next day the airport was still closed. I rent a car and went to Warsaw. But this is a different story :-)

I'm really looking forward to the next Trinity Java User Group meeting. I'm curious what happens then :-).

See you at Java EE Workshops at Munich Airport, Terminal 2 or dedicated virtual workshops!


NEW workshop: Microservices with Java EE 7 and Java 8, January 26th, 2015, Airport Munich

A book about rethinking Java EE Patterns

Setting Timeout For The JAX-RS 2.0 / Jersey Client

Timeouts are crucial for robustness of the communication between reasonable WARs (also known as micro services).

Timeout settings are not standardized and have to be passed as "proprietary" properties of the JAX-RS client:


import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import org.glassfish.jersey.client.ClientProperties;

        Client client = ClientBuilder.newClient();
        client.property(ClientProperties.CONNECT_TIMEOUT, 100);
        client.property(ClientProperties.READ_TIMEOUT, 10);


The "provided" dependency highlighted above can be omitted by using the String representation of the constants:

        client.property("jersey.config.client.connectTimeout", 100);
        client.property("jersey.config.client.readTimeout", 10);


Timeouts will cause: java.net.SocketTimeoutException: Read timed out exception which can be easily handled. A few years ago we would talk about exception handling and robustness, in the age of micro services we can call it now "resilience" :-).

See you at Java EE Workshops at Munich Airport, Terminal 2 or at a virtual, dedicated workshop!


NEW workshop: Microservices with Java EE 7 and Java 8, January 26th, 2015, Airport Munich

A book about rethinking Java EE Patterns

Introducing afterburner.fx TopGun Edition

afterburner.fx is the leanest possible MVP / MVVM "framework" for Java FX 8 / Java 8.

As afterburner.fx became more popular, I got many interesting community contributions. I rejected most of the pull requests, because I could not find the "killer use case" for most of them. afterburner.fx should remain lean and simple.

The solution to this unsatisfying situation is the branch topgun. Recent pull requests, like e.g. weld integration and support for @Named qualifiers are already merged.

In addition the "topgun" edition is also available from maven central:


<dependency>
	<groupId>com.airhacks</groupId>
	<artifactId>afterburner-topgun.fx</artifactId>
	<version>1.6.2</version>
</dependency>

There are no changes for coordinates of the default afterburner.fx:


<dependency>
	<groupId>com.airhacks</groupId>
	<artifactId>afterburner.fx</artifactId>
	<version>[LATEST_RELEASE]</version>
</dependency>

Now all contributions are welcome. Use the branch: topgun as base for feature implementations and the default branch master for possible bug fixes.

See you at Java EE Workshops at Munich Airport!


NEW workshop: Microservices with Java EE 7 and Java 8, January 26th, 2015, Airport Munich

A book about rethinking Java EE Patterns

Service Discovery, Micro Service Communication, Fast Deployments, JPA-JSON Serialization, ECB again or 9th Airhacks Q&A

Questions for the 1st December, Monday, 6 P.M. CET, 9th edition of the http://airhacks.tv show:

  1. @AdamBien what would be your take on how to most elegantly deal with resilience and service discovery for JavaEE7 #microservices ? (tweet by @niko_nava)

  2. OData vs. RAW Json (email question from Louw)

  3. what logging framework do you normally use? Seems slf4j is the only library i can’t get rid of in my WARs… (tweet @MichelSchudel)

  4. How to transform entities with OneToMany relationships into json for JAX-RS (lazyinitialization exception is thrown if relationship is not fetched)? Let’s say I have methods getAllUsers() and getAllUsersWithDetails(). I was able to do it with jackson and its jackson-datatype-hibernate dependency. Is there any other, better way? MougLee

  5. I have seen your videos on ECB pattern, but I am not sure, what goes into Control and what into Boundary. You said, that you do it with refactoring, when Boundary gets to big … Could you please provide any more pointers? MougLee

  6. I have a feeling, I have to deploy/redeploy my application all the time during development. Do you have any tips to speed up development as much as possible and avoid deploying code? Without JRebel :-) MougLee

  7. What’s in your opinion the preferred way to handle service-versioning for REST services? mliebl

  8. We are running a JEE application with thousands of EJBs (EAR with 3 different projects refered) which takes around 10 minutes for server start up. Mainly time spent on creating and loading EJBs at startup. How can I bring down the startup time of Jboss server at least in development environment. surendrand

  9. What is the most efficient way to communicate between two μ-Services especially 1. when they are deployed as different WARs and 2. on different Docker images but on the same Docker “Host”/VM/machine. 0x001D

  10. What do you do for simple reporting in enterprise projects ?? Use a BI solution and integrate it ? any alternative ? cristhiank

  11. What are the possible solutions for API Gateway in JavaEE enviroments. Specifically when there is different JavaEE app per business line exposing RestAPIS. tegbird

  12. What are ur views on API management tools provided by vendors as centralized solution to APIs. Is it going the same way as ESBs did to SOA. Nobody understood them, overated and underused. tegbird

  13. I would like to ask you what is more preferable in your opinion: serializing enums to json using enum names in order to send via rest or using enum values instead of enum names for example in case as below: RED(“red”), BLUE(“blue”); 4tran

  14. sometimes you are talking about your personal server you build every 3 years. Can you provide some details (list of components) about your current configuration? github0x1

  15. Most of my JavaFX applications have composite views and so the sub-views have to communicate with each other. I hate nesting controllers using @FXML injection. I think it creates a strong coupling between the views. I use afterburner.fx in most of my projects. What do you think is the best way to communicate across sub-views within a composite view? Thanks. raghsr

  16. I have a hierarchy of organization unit objects (plants, centers, departments, teams, …). Each object has a reference to his parent and his children (getParent(), getChildren()). Everything is loaded and wired during application initialization and I have a service which provides me the object (getObjectByID, …) Now my problem: I want to allow and deny the access to the objects dependent on the user. Is there an easy JEE/CDI way to reach this goal? I mean, how do I tell the plantOrgUnit-Object to deliver only children or parent OrgUnit-Objects which are are permitted (eg by a criteria like a role, or an attribute reflecting the role relation)? May be the question is too stupid. Then please skip it. If you have any modern CDI/EE6 way to handle such kind of problems please provide it (Karsten)

Do you have any additional questions? Ask now, file them https://gist.github.com/AdamBien/a048fa8262ad12069e94 or wait a month :-)

The best of all: you can ask the questions live, during the show using the chat: http://www.ustream.tv/channel/adambien, twitter (hashtag "#airhacks") or (the best option): using channel ##airhacks on http://freenode.net.

See also other screencasts at: http://tv.adam-bien.com or subscribe tohttp://www.youtube.com/user/bienadam.

See you at Java EE Workshops at Munich Airport, Terminal 2.


NEW workshop: Microservices with Java EE 7 and Java 8, January 26th, 2015, Airport Munich

A book about rethinking Java EE Patterns

JAX-RS 2.0 Client: Retrieving A List Of Instances, Problem and Solution

Retrieving a generic List in a JAX-RS 2.0 client:


List<Workshop> all = this.contextURI.request(MediaType.APPLICATION_XML).get(List.class);

Does not carry sufficient amount of information to deserialize the payload and leads to following (or similar exception):

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: 
MessageBodyReader not found for media type=application/xml, type=interface java.util.List, genericType=interface java.util.List.
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:230)
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154)
	at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124)
	at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851)
	at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:783)


The javax.ws.rs.core.GenericType helper solves the problem by wrapping the List and providing the necessary information to the built-in deserializer (MessageBodyReader):

import javax.ws.rs.core.GenericType;

List<Workshop> all = target.request(MediaType.APPLICATION_XML).get(new GenericType<List<Workshop>>() {});

There is a symmetric challenge on the server counterpart sending the list to the client.

See you at Java EE Workshops at Munich Airport, Terminal 2 particularly at Effective Java EE!


NEW workshop: Microservices with Java EE 7 and Java 8, January 26th, 2015, Airport Munich

A book about rethinking Java EE Patterns

realworldpatterns.com
...the last 150 posts
...the last 10 comments
License