<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>test</groupId> <artifactId>test</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.tomee</groupId> <artifactId>javaee-api</artifactId> <version>8.0-3</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.microprofile</groupId> <artifactId>microprofile</artifactId> <version>2.0</version> <type>pom</type> <scope>provided</scope> <exclusions> <exclusion> <groupId>javax.json</groupId> <artifactId>javax.json.bind-api</artifactId> </exclusion> <exclusion> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> </exclusion> <exclusion> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> </exclusion> <exclusion> <groupId>javax.json</groupId> <artifactId>javax.json-api</artifactId> </exclusion> <exclusion> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.myfaces.core</groupId> <artifactId>myfaces-api</artifactId> <version>2.3.6</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>test</finalName> <plugins> <plugin> <groupId>org.apache.tomee.maven</groupId> <artifactId>tomee-embedded-maven-plugin</artifactId> <version>8.0.2</version> <configuration> <context>ROOT</context> <containerProperties> <tomee.mp.scan>true</tomee.mp.scan> </containerProperties> </configuration> <dependencies> <dependency> <groupId>org.apache.tomee</groupId> <artifactId>mp-common</artifactId> <version>8.0.2</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> </plugin> </plugins> </build> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> </project>
Software Development
Wednesday, June 24, 2020
How to use Microprofile with tomee-embedded-maven-plugin
Here is a sample POM how to use Microprofile with tomee-embedded-maven-plugin 8.x:
Tuesday, March 12, 2019
Tuesday, March 5, 2019
Way to MyFaces 2.3-next
I (and other commiters) spend many hours to prepare the MyFaces codebase for the upcoming version 2.3-next during the last months, which will be MyFaces 4.0 in the future.
JSF (or Jakarta Faces) 3.0 will be 1:1 the same as JSF 2.3, just with the jakarta.* package names.
In 2.3-next, we did BIG BIG cleanup of our codebase and build.
Wee also removed the old JSF EL (javax.faces.el.*) and @ManagedBean (javax.faces.bean.*) implementations.
What does this mean? The API (javax.faces.el.*) and (javax.faces.bean.*) is still there but the implementation of it has been removed partially. @ManagedBean's are now registered as CDI beans, which means that a CDI runtime is a required dependency now.
The biggest clenaup was that we merged back the "shared" and "shared-public" modules to myfaces-impl, as the shared modules are no longer used by other active projects under the MyFaces umbrella.
We also introduced some real integration tests with Arquillian, to test parts of the container integration and AJAX client side. This makes around 1600 unittests!
OK.... Lets compare some numbers!
JAR size:
Performance:
NOTE: this is not a full benchmark, it's only a single case to demonstrate the difference between MyFaces 2.3 and MyFaces 2.3-next, which was inspired from: https://www.oio.de/public/java/studie-jsf-mojarra-myfaces-performance-vergleich.htm
We have to rerun https://github.com/lu4242/performance-comparison-java-web-frameworks later for a real comparison between MyFaces and Mojarra.
This means that MyFaces 3.0 is up to ~15% faster as the already very fast MyFaces 2.3 in this case.
We also did some memory finetuning - i just don't have any numbers right now.
JSF (or Jakarta Faces) 3.0 will be 1:1 the same as JSF 2.3, just with the jakarta.* package names.
In 2.3-next, we did BIG BIG cleanup of our codebase and build.
Wee also removed the old JSF EL (javax.faces.el.*) and @ManagedBean (javax.faces.bean.*) implementations.
What does this mean? The API (javax.faces.el.*) and (javax.faces.bean.*) is still there but the implementation of it has been removed partially. @ManagedBean's are now registered as CDI beans, which means that a CDI runtime is a required dependency now.
The biggest clenaup was that we merged back the "shared" and "shared-public" modules to myfaces-impl, as the shared modules are no longer used by other active projects under the MyFaces umbrella.
We also introduced some real integration tests with Arquillian, to test parts of the container integration and AJAX client side. This makes around 1600 unittests!
OK.... Lets compare some numbers!
JAR size:
Mojarra 2.3 | MyFaces 2.3 | MyFaces 2.3-next | |
---|---|---|---|
API |
1318 kb | 1043 kb | |
IMPL | 3495 kb (combined) | 2712 kb | 2384 kb |
Dependencies |
241 kb (beanutils) 141 kb (digester) |
||
TOTAL | 3495 kb | 4412 kb | 3427 kb |
Performance:
NOTE: this is not a full benchmark, it's only a single case to demonstrate the difference between MyFaces 2.3 and MyFaces 2.3-next, which was inspired from: https://www.oio.de/public/java/studie-jsf-mojarra-myfaces-performance-vergleich.htm
We have to rerun https://github.com/lu4242/performance-comparison-java-web-frameworks later for a real comparison between MyFaces and Mojarra.
Mojarra 2.3 | MyFaces 2.3 | MyFaces 2.3-next | |
---|---|---|---|
GET input.xhtml | Average: 67 ms | Average: 62 ms | Average: 43 ms |
POST input.xhtml | Average: 115 ms | Average: 122 ms | Average: 108 ms |
GET detail.xhtml | Average: 119 ms | Average: 124 ms | Average: 103 ms |
POST detail.xhtml | Average: 70 ms | Average: 54 ms | Average: 43 ms |
TOTAL | Average: 92 ms Throughput: 198.7/s |
Average: 91 ms Throughput: 209.8/sec |
Average: 74 ms Throughput: 264.2/sec |
This means that MyFaces 3.0 is up to ~15% faster as the already very fast MyFaces 2.3 in this case.
We also did some memory finetuning - i just don't have any numbers right now.
Tuesday, February 5, 2019
Maven: use lombok combined with OpenJPA metadata generation
Here is a example how to use lombok combined with OpenJPA metadata generation inside the maven-compiler-plugin:
<dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.0</version> </dependency> <!-- needs to be defined here for the annotation processor --> <dependency> <groupId>org.apache.openjpa</groupId> <artifactId>openjpa</artifactId> <version>3.0.0</version> <optional>true</optional> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>${maven.compiler.source}</source> <target>${maven.compiler.target}</target> <annotationProcessors> <annotationProcessor>lombok.launch.AnnotationProcessorHider$AnnotationProcessor</annotationProcessor> <annotationProcessor>org.apache.openjpa.persistence.meta.AnnotationProcessor6</annotationProcessor> </annotationProcessors> <compilerArgs> <arg>-Aopenjpa.metamodel=true</arg> <arg>-Aopenjpa.source=7</arg> </compilerArgs> </configuration> </plugin> </plugins> </pluginManagement> </build>
Tuesday, November 7, 2017
Increase your JSF application performance - Version 2017
As my last posts are already 5 years old, i think it's time for a new one :D
If you would like to use a JavaEE application server, i would go with TomEE.
It's the fastest and smallest application server available and already comes with Apache MyFaces as JSF implementation and Apache OpenWebBeans as CDI implementation.
There are already really good benchmarks available why we should choose MyFaces over Mojarra and OpenWebBeans over Weld:
Understanding JSF 2.0 Performance – Part 1
Understanding JSF 2.0 Performance – Part 2
Understanding JSF 2.0 Performance – Part 3
CDI Performance
So if you just use a plain servlet container like Tomcat or Jetty, i would also use MyFaces and OpenWebBeans.
In the past it was also a good performance boost if you use JUEL over Tomcat's EL implementation - sadly JUEL doesn't implement EL 3.0.
Enable ViewPooling: http://lu4242.blogspot.de/2013/12/view-pooling-in-jsf-22-using-apache.html
NOTE: You must also set:Enable WhiteSpace compression: http://lu4242.blogspot.de/2012/12/html-white-space-compression-for-jsf.html
Disable JSP support in MyFaces - this increases the startup performance and EL resolution:
Disable ManagedBeans support (since 2.3):
Reduce saved view states:
Disable ViewState compression (better performance but more memory usage):
Enable partial submit in PrimeFaces - this reduces the network traffic:
Move above the fold scripts to the bottom (end of body). This is a huge improvement of the visible rendering and removes flickering between navigations (since 6.2):
Other params to increase performance:
Use a custom ServletFilter to set the correct expires/cache headers of your resources (images, stylesheets, javascripts). This is only required if you don't use the JSF resource handling for every resource. The JSF impl should already do it correctly for all JSF managed resources.
Compress and optimize your Javascripts in your build process. If you
use maven, try primefaces-extensions' closure compiler maven plugin.
Enable GZIP in your webserver! If it's not supported by your webserver/container, you can still add the GzipResponseFilter from OmniFaces: http://showcase.omnifaces.org/filters/GzipResponseFilter
Environment:
If you would like to use a JavaEE application server, i would go with TomEE.
It's the fastest and smallest application server available and already comes with Apache MyFaces as JSF implementation and Apache OpenWebBeans as CDI implementation.
There are already really good benchmarks available why we should choose MyFaces over Mojarra and OpenWebBeans over Weld:
Understanding JSF 2.0 Performance – Part 1
Understanding JSF 2.0 Performance – Part 2
Understanding JSF 2.0 Performance – Part 3
CDI Performance
So if you just use a plain servlet container like Tomcat or Jetty, i would also use MyFaces and OpenWebBeans.
In the past it was also a good performance boost if you use JUEL over Tomcat's EL implementation - sadly JUEL doesn't implement EL 3.0.
Configuration:
- Common settings:
<context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Production</param-value> </context-param> <context-param> <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name> <param-value>-1</param-value> </context-param> <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>server</param-value> </context-param>
<context-param> <param-name>org.apache.myfaces.CACHE_EL_EXPRESSIONS</param-name> <param-value>alwaysRecompile</param-value> </context-param>
<context-param> <param-name>org.apache.myfaces.SUPPORT_JSP_AND_FACES_EL</param-name> <param-value>false</param-value> </context-param> <!-- NOTE: the ExpressionFactory might differ e.g. on Glassfish or Wildfly. This parameter is optional since MyFaces 2.3.3. --> <context-param> <param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name> <param-value>org.apache.el.ExpressionFactoryImpl</param-value> </context-param>
<context-param> <param-name>org.apache.myfaces.SUPPORT_MANAGED_BEANS</param-name> <param-value>false</param-value> </context-param>
<context-param> <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name> <param-value>15</param-value> </context-param> <context-param> <param-name>org.apache.myfaces.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION</param-name> <param-value>3</param-value> </context-param>
<context-param> <param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name> <param-value>false</param-value> </context-param>
<context-param> <param-name>primefaces.SUBMIT</param-name> <param-value>partial</param-value> </context-param>
<context-param> <param-name>primefaces.MOVE_SCRIPTS_TO_BOTTOM</param-name> <param-value>true</param-value> </context-param>
<context-param> <param-name>org.apache.myfaces.CHECK_ID_PRODUCTION_MODE</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>org.apache.myfaces.EARLY_FLUSH_ENABLED</param-name> <param-value>true</param-value> </context-param>
Patterns:
- Correctly define update/render and process/execute! Often this is a huge improvement as many times the whole form is updated instead only a small part. But i also prefer maintainability over performance here.
- If you don't use ViewScoped beans, it's a good but small improvement to mark the view as stateless via transient=true.
- Try using HTML over JSF tags.
- Especially avoid using h:outputText if you don't need the escaping. Just use EL expressions inside your xhtml template.
- The same applies for some other components like p:outputPanel. Just use a plain div. If you need to make it updateable, you can still use "passtrough elements" (<div jsf:id="...">...</div>)
- Never put logic in getters because they can be called multiple times - especially for the rendered attribute!
- Avoid logic (like inline if-statements) in EL expression! It's better to move those logic into the bean. It's faster and often easier to read and maintain.
- Prefer AJAX over a full postback!
- If you have many p:outputLabel's on the page and you know that the input field is required or not, it's a good performance improvemet to set the input to required=true or the outputLabel to indicateRequired=true|false. The default value for indicateRequired since 6.2 is auto, which tries to lookup BeanValidation constrains to check if @NotNull|@NotEmpty|@NotBlank are defined.
- Cache data, which is required multiple times in the same view, in @RequestScoped beans.
- Avoid missusing @SessionScoped, @ViewScoped and other long living scopes if not really required.
- Try to put only small amount of data in such long living beans. Sometimes a small flag or id of an entity is enough information. Often people put many entities in such long living beans. One of my patterns is to split beans into *Controllers (@RequestScoped) and *StateHolders (@ViewScoped, @ViewAccessScoped). *StateHolders are just data containers.
Monday, January 25, 2016
Enable failover with OpenWebBeans (>= 1.5.1)
Since OWB 1.5.1 you don't need any configuration or FailOverFilter anymore as the beans are directly stored in the HttpSession :)
Saturday, September 21, 2013
Session replication / clustering / failover with Tomcat (Part 1 - Overview)
This is my first post of a series about Tomcat and clustering.
In this post i will explain some different replication mechanism.
NOTE: A common drawback of replication, like it's defined in the specs, is that only HttpSession#setAttribute(...) triggers replication.
This means that if you store a container object in the session and if you change a variable inside the object, you must HttpSession#setAttribute(...) again to replicate the modified object again.
Many frameworks implements a simple workaround for it - i will write about it another post.
With this mode, Tomcat just replicates the session to all registered nodes.
Pro:
The sessions will be replicated to the next neighbor. If one Tomcat is not available anymore, the neighbor still holds the sessions.
Pro:
Each Tomcat replicates all sessions to N (multiple) Memcached nodes.
If a session is not available on the local Tomcat, the memcached-session-manager tries to lookup the session from the Memcached nodes.
Pro:
In this post i will explain some different replication mechanism.
NOTE: A common drawback of replication, like it's defined in the specs, is that only HttpSession#setAttribute(...) triggers replication.
This means that if you store a container object in the session and if you change a variable inside the object, you must HttpSession#setAttribute(...) again to replicate the modified object again.
Many frameworks implements a simple workaround for it - i will write about it another post.
All to all replication / DeltaManager
With this mode, Tomcat just replicates the session to all registered nodes.
Pro:
- No single point of failure at software level
- Every node holds all sessions
- In theory, all other nodes can be turned off
- No extra software is needed
- Synchronous or Asynchronous replication
- Open Source
- Enterprise-Support available
- High memory usage and network traffic because all nodes holds all sessions
- Objects which are stored in the session must be triggered manually to replicate again if a property has been changed
- Slower session serialization
Primary/Secondary Replication (Buddy Replication) / BackupManager
The sessions will be replicated to the next neighbor. If one Tomcat is not available anymore, the neighbor still holds the sessions.
Pro:
- No single point of failure at software level
- Lower memory usage and network traffic because the session is not stored on all nodes
- No extra software is needed
- Synchronous or Asynchronous replication
- Open Source
- Enterprise-Support available
- Not quite as battle tested as the All-to-all replication (see Tomcat documentation)
- Objects which are stored in the session must be triggered manually to replicate again if a property has been change
- Slower session serialization
Memcached-session-manager
Each Tomcat replicates all sessions to N (multiple) Memcached nodes.
If a session is not available on the local Tomcat, the memcached-session-manager tries to lookup the session from the Memcached nodes.
Pro:
- No single point of failure at software level
- More scalability
- Session will be replicated to N “Memcached” nodes – The sessions are still available if all webservers are down
- Automatically handles “Memcached” nodes failover
- Sticky mode: Lower memory usage because every node holds only the current used sessions
- Non-Sticky mode: Lowest memory usage because Tomcat does not hold the sessions anymore. Session will be received from memcached for each request
- MSM will automatically trigger replication if a property in a session stored object has been changed
- Faster session serialization – Changeable mechanism
- Synchronous or Asynchronous replication
- Open Source
- Enterprise-Support available for Tomcat
- Extra software needed (“Memcached” plugin and nodes)
- Cannot switch to another Java Webserver which does not automatically check changed values in the session - but only if the used framework has no implemented workaround
- AFAIK no Enterprise-Support available for the Memcached plugin but Martin Grotzke is very active on the mailing list
Subscribe to:
Posts (Atom)