TomEE Embedded improvements for the v7.0.2
TomEE Embedded got a huge booster in term of usability and power with the 7.x branch thanks to Tomcat 8 refactoring. However some features were still hard to obtain without writing yourself a main or wrapping it in some custom glue code.
With 7.0.2 the goal is to make it even more flexible and user friendly.
FatApp or the main with good defaults
TomEE Embedded was originally not design for classpath deployments but for embedded deployments of war/jar/ear files. Therefore its defaults don't always match a uber jar application. That is the goal of the FatApp main which is just a wrapper to default TomEE Embedded main with three automatically activated options:
- --as-war: to deploy the classpath as a webapp
- --single-classloader: to ensure the application can inherit the boot classloader
- --configuration-location=tomee-embedded.properties: this is a new property explained later but basically it provides a way to automatically load configuration from the classpath
To use that just replace Main by FatApp when specifying TomEE main on the command line.
New CLI options
The cli wired more options now usable from outside the code:
- we already mentionned --configuration-location which takes a location as parameter (either from classpath or file path) and load its content as TomEE embedded properties configuration. It allows to configure most of the server including port, host, server.xml, temporary directoy, SSL, ....
- --pre-task: allows to define some task executed before the container starts (and to stop them after the container stops if it implements LifecycleTask instead of a plain Runnable). This is quite common to embedded another server like a SFTP, OrientDB, ...or just have a custom preconfiguration task using a custom repository
- --classes-filter: this configures a XBean Filter (similar to a java 8 predicate) to be able to filter programmatically classes you want to scan or ignore. For uber jar this can significantly boost your application startup and reduce the memory used during this phase.
- --basic: if activated it will automatically secure the application behind a BASIC authenticator
LoginConfig and SecurityConstraint are not wired to the CLI directly cause it requires some more configuration and would lead to a lot of options but they are accessible through the --configuration-location one. For instance to secure /api/* with JAAS you can provide a mysecurityconfig.properties like this snippet:
# secure /api/* and give "api" as name for the constraint
securityConstraint =
securityConstraint.authConstraint = true
securityConstraint.authRole = **
securityConstraint.collection = api:/api/*
# use basic for "app"
login =
login.realmName = app
login.authMethod = BASIC
# use jaas
realm = org.apache.catalina.realm.JAASRealm
realm.appName = app
# use the global jaas entry but we could have configure a
#Â configFile on realm to use a classpath one
properties.java.security.auth.login.config = configuration/login.jaas
Another usage of that file is to configure the logging framework since it is really easy to switch it with TomEE embedded (far easier than in a plain TomEE you don't control for instance):
# ensure to have these dependencies:
# <dependency>
# <groupId>org.apache.logging.log4j</groupId>
# <artifactId>log4j-core</artifactId>
# <version>${log4j2.version}</version>
# </dependency>
# <dependency>
# <groupId>org.apache.logging.log4j</groupId>
# <artifactId>log4j-slf4j-impl</artifactId>
# <version>${log4j2.version}</version>
# </dependency>
# <dependency> <!-- optional -->
# <groupId>org.apache.logging.log4j</groupId>
# <artifactId>log4j-web</artifactId>
# <version>${log4j2.version}</version>
# </dependency>
properties.openejb.log.factory = log4j2
Having this configuration there will avoid to have to set it on the command line which is quite nice and allows you to package your own application with some presets.
TomEEEmbeddedApplicationRunner: an air of ApplicationComposer
If you don't know OpenEJB ApplicationComposer, it is a way to configure the application programmatically and run the described application instead of relying on a full scanning.
ApplicationComposer is usable for most applications without a frontend and allows to deploy your own application with most of EE features but sometimes you need more and in particular a web server.
For that purpose TomEEEmbeddedApplicationRunner started to support ApplicationComposer options for TomEE Embedded. It is not complete yet but allows to run your application differently already. Let's take a quick tour of that new runner!
The idea behind this feature is, as for ApplicationComposer, to define an application. For TomEE Embedded runner it looks like it:
@Application // optional if passed to run method
@Classes(context = "app")
@ContainerProperties(@ContainerProperties.Property(name = "t", value = "set"))
@TomEEEmbeddedApplicationRunner.LifecycleTasks(MyTask.class) // can start a ftp/sftp/elasticsearch/mongo/... server before tomee
@TomEEEmbeddedApplicationRunner.Configurers(SetMyProperty.class)
public class TheApp {
@RandomPort("http")
private int port;
@RandomPort("http")
private URL base;
@org.apache.openejb.testing.Configuration
public Properties add() {
return new PropertiesBuilder().p("programmatic", "property").build();
}
@PostConstruct
public void appStarted() {
// ...
}
}
As you can see it already supports several features:
- @Classes: when value() is not set it will deploy the classpath but if you set value it will deploy the list of classes there. In this last case if you need some dependencies in the classpath you can use @Jars to add them (for instance @Jars("deltaspike-"))
- @ContainerProperties: this is a way to set/hardcode container properties. Note that the nice thing is if your application supports to read your configuration from system properties this will work too. The last awesome feature there is that it also supports placeholders in values.
- @LifecycleTasks: allows to define a list of lifecycle tasks as defined in previous part. Very common to start another local server or retrieve configuration from a custom location.
- @Configurers: configurers are consumers of the server configuration allowsing to customize it programmatically. One use case today is to configure HTTP2.
- @RandomPort: allow to start with a dynamically allocated port
- @Configuration: programmatic equivalent to @ContainerProperties
- Finally lifecycle hooks (@PostConstruct/@PreDestroy) are supported in the application class and executed once the application is deployed (before for @PreDestroy)
Conclusion
These new features makes it very easy to embed TomEE and provide a full package for your application for the production side of things but it also means an easier debugging and development since you control a "main" and no more a server with its own layout, structure etc...
This opens a lot of new doors but keep in mind whatever noise is done on the net, this doesn't mean "fat jar", it just means adapted packaging to your need which can still be compatible with having a team responsible of the application, one of the server if needed since the classpath can be split physically. In summary: no need to do the war to fat jar or exploded deployments, TomEE embraces both!
From the same author:
In the same category: