Java EE 7 platform added a few new specifications to the platform:
- Java API for WebSocket 1.0
- Batch Applications for Java 1.0
- Java API for JSON Processing 1.0
- Concurrency Utilities for Java EE 1.0
This is highlighted in the pancake diagram shown below:
Several of the existing specifications were updated to fill the gaps and provide a more cohesive platform. Some small, but rather significant additions, were made to the platform to provide defaults for different features. These defaults would lower the bar for application developers to build Java EE applications.
Lets take a look at them.
- Default CDI: Java EE 6 required “beans.xml” in an archive to enable CDI. This was mostly a marker file. So you could bundle a completely empty “beans.xml” in the archive and that would enable injection. Of course, you could specify a lot of other elements in this file such as interceptors, decorators, alternative but the basic dependency injection was enabled by just the mere inclusion of this file.This was one of the biggest source of confusion of why beans were not getting injected in a Java EE 7 archive, and was asked on several forums and other channels.
Java EE 7 made that “beans.xml” optional and provided a default behavior. Now if this file is not bundled, all CDI-scoped beans are available for injection. So any bean with an explicitly specified scope is available for injection. Scopes defined by the CDI specification are listed at docs.oracle.com/javaee/7/api/javax/enterprise/context/package-summary.html. Specifically, here are the scopes defined by CDI:
- @ApplicationScoped
- @ConversationScoped
- @Dependent
- @NormalScope
- @RequestScoped
- @SessionScoped
In addition, two new scopes are introduced in Java EE 7:
- @FlowScoped
- @TransactionScoped
So, any bean with these scopes will be available for injection, in other beans only, without the presence of “beans.xml”.
Check it out in action at github.com/javaee-samples/javaee7-samples/tree/master/cdi/nobeans-xml.
- Default data source: A Java EE runtime, a.k.a application server, requires to package a database with it. If you are building a Java EE application, you likely will need some sort of data store or RBDMS to store the data. So this makes perfect sense.For example, WildFly bundles in-memory H2 database.Now, you can certainly use another JDBC-compliant database but bundling a database makes it convenient to start with. However, in order to get started, Java EE 6 still required to create JDBC resources in an application server-specific way. This would mean understanding app server-specific tools.
Java EE 7 simplified it by providing a default data source with a pre-defined JNDI name.This mean you can inject a data source as:
@Resource DataSource ds;
Also, your persistence.xml can look like:
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="myPU" transaction-type="JTA"/> </persistence>
Note, no <jta-data-source>.
In both of these circumstances, a default data source with JNDI name
java:comp/DefaultDataSource
is bound to your application-server specific JDBC resource.The exact data source in WildFly can be verified using jboss-cli script as:
wildfly-8.1.0.Final> ./bin/jboss-cli.sh --connect --command="/subsystem=datasources:read-resource" { "outcome" => "success", "result" => { "data-source" => {"ExampleDS" => undefined}, "jdbc-driver" => {"h2" => undefined}, "xa-data-source" => undefined } }
Check it out in action at github.com/javaee-samples/javaee7-samples/tree/master/jpa/default-datasource.
- Create JMS connection factory, queues, and topics: An application using JMS topics and queues in Java EE 6 would require a deployment script to create Connection Factory and Queues/Topics. These would again be done in an application server-specific way.Java EE 7 provide annotations
@JMSConnectionFactoryDefinition
and@JMSConnectionFactoryDefinitions
that are read by the Java EE 7 runtime and ensures that theConnectionFactory
specified by these annotations is provisioned in the operational environment.Similarly,
@JMSDestinationDefinition
and@JMSDestinationDefinitions
can be used to create Topics/Queues as part of application deployment.So no more deployment scripts, just include annotation in your code ?Check it out in action at github.com/javaee-samples/javaee7-samples/tree/master/jms/send-receive.
- Default JMS connection factory: Just like default data source, a default JMS resource allows you to avoid creating a
JMSConnectionFactory
in an appserver-specific way to deploy the application using JMS resources.Injection of a JMSProducer
orConsumer
in Java EE 6 required to get an instance of application-managed or container-managedJMSConnectionFactory
. This factory had to be manually created in an application-server specific way.Providing a defaultJMSConnectionFactory
simplifies this step further.JMS 2.0 also introduced
JMSContext
as entry point to the simplified API, and it can be injected simply as:@Inject JMSContext context;
Not specifying a
ConnectionFactory
means the default one will be used. And it has the JNDI name ofjms/DefaultJMSConnectionFactory
.The JNDI name may be mapped to the appserver-specific JMS provider. For example, in case of WildFly it is defined as:
./bin/jboss-cli.sh -c --command="/subsystem=messaging/hornetq-server=default/pooled-connection-factory=hornetq-ra:read-resource" { "outcome" => "success", "result" => { "auto-group" => false, "block-on-acknowledge" => false, "block-on-durable-send" => true, "block-on-non-durable-send" => false, "cache-large-message-client" => false, "call-failover-timeout" => -1L, "call-timeout" => 30000L, "client-failure-check-period" => 30000L, "client-id" => undefined, "compress-large-messages" => false, "confirmation-window-size" => -1, "connection-load-balancing-policy-class-name" => "org.hornetq.api.core.client.loadbalance.RoundRobinConnectionLoadBalancingPolicy", "connection-ttl" => 60000L, "connector" => {"in-vm" => undefined}, "consumer-max-rate" => -1, "consumer-window-size" => 1048576, "discovery-group-name" => undefined, "discovery-initial-wait-timeout" => undefined, "dups-ok-batch-size" => 1048576, "entries" => [ "java:/JmsXA", "java:jboss/DefaultJMSConnectionFactory" ], "failover-on-initial-connection" => false, "failover-on-server-shutdown" => undefined, "group-id" => undefined, "ha" => false, "initial-connect-attempts" => 1, "initial-message-packet-size" => 1500, "jndi-params" => undefined, "max-pool-size" => -1, "max-retry-interval" => 2000L, "min-large-message-size" => 102400, "min-pool-size" => -1, "password" => undefined, "pre-acknowledge" => false, "producer-max-rate" => -1, "producer-window-size" => 65536, "reconnect-attempts" => -1, "retry-interval" => 2000L, "retry-interval-multiplier" => 1.0, "scheduled-thread-pool-max-size" => 5, "setup-attempts" => undefined, "setup-interval" => undefined, "thread-pool-max-size" => 30, "transaction" => "xa", "transaction-batch-size" => 1048576, "use-auto-recovery" => true, "use-global-pools" => true, "use-jndi" => undefined, "use-local-tx" => undefined, "user" => undefined } }
Check it out in action at github.com/javaee-samples/javaee7-samples/tree/master/jms/send-receive.
- Default executors: Concurrency Utilities for Java EE introduced four different managed objects:
- ManagedExecutorService
- ScheduledManagedExecutorService
- ContextService
- ManagedThreadFactory
These objects allow user to create application threads that are managed by the Java EE server runtime. Once again, a default and pre-configured managed object, with a well-defined JNDI name, is made available for each one of them.
This allows a user to inject a ManagedExecutorService as:
@Resource ManagedExecutorService myExecutor;
instead of:
@Resource(lookup="myExecutorJNDI") ManagedExecutorService myExecutor;
Default ManagedExecutorService in WildFly can be found as:
./bin/jboss-cli.sh -c --command="/subsystem=ee/managed-executor-service=default:read-resource" { "outcome" => "success", "result" => { "context-service" => "default", "core-threads" => 5, "hung-task-threshold" => 60000L, "jndi-name" => "java:jboss/ee/concurrency/executor/default", "keepalive-time" => 5000L, "long-running-tasks" => false, "max-threads" => 25, "queue-length" => 0, "reject-policy" => "ABORT", "thread-factory" => undefined } }
Similarly other default managed objects can be found.
Check out different executors in action at github.com/javaee-samples/javaee7-samples/tree/master/concurrency.
With so many simplifications, why would you not like to use Java EE 7 platform ?
And WildFly is a fantastic application server too
Download WildFly now, and get started!