tag:blogger.com,1999:blog-44988893534287103132024-03-13T14:22:33.374-07:00Arjan Tijms' WeblogMusings of a Java EE developerArjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.comBlogger95125tag:blogger.com,1999:blog-4498889353428710313.post-90608097232897550942022-12-23T11:45:00.000-08:002022-12-23T11:45:48.921-08:00Close them out!Having a good backlog is important for many projects. However, having hundreds or even thousands of issues that realistically nobody will ever pick up does not constitute a good backlog.
<p>
Just closing out old issues can be the best thing one can do.<i> <br/>(click on the image for a larger version)</i>
</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrmZ6wCKhvNgDm1oLfJh7-GOVYThgBErWRyflk9NQqLY-KNADpOacWW1eHgdwZ5OlSiseAx8ks9h-vby_PVPqtoZQDf-AQWnryNRtcY1sgdK0hPp63l36gPa11DSK-LpASJMJfmySAd_9LDek8nPKoy47IrGCVYpQJd7Y6hhwT_ZHsrOMWwWJo9q_q0A/s1600/omnidevs_comic6.jpg" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" border="0" data-original-height="2480" data-original-width="3508" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrmZ6wCKhvNgDm1oLfJh7-GOVYThgBErWRyflk9NQqLY-KNADpOacWW1eHgdwZ5OlSiseAx8ks9h-vby_PVPqtoZQDf-AQWnryNRtcY1sgdK0hPp63l36gPa11DSK-LpASJMJfmySAd_9LDek8nPKoy47IrGCVYpQJd7Y6hhwT_ZHsrOMWwWJo9q_q0A/s1600/omnidevs_comic6.jpg"/>
</a>
</div>
<p>
<a href="https://i.imgur.com/GNOzNtP.jpg">Even larger version</a>
</p>
<p>
Stay tuned for the next instalment!</p>
<p>
Previous strip: <a href="https://arjan-tijms.omnifaces.org/2022/12/just-say-no.html">Just say no
</a>Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-89525324237831841062022-12-14T10:08:00.002-08:002022-12-23T11:51:08.735-08:00Just say noDevelopers want to be there for everyone, and are always ready to help out with their coding skills.
<p>
An experienced developer however doesn't just know when to say yes, but especially knows when to say no.<i> <br/>(click on the image for a larger version)</i>
</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_Y8Wnrm-rvAHnDlP3Ozjxx_ehIivrrkowdbHMspyHCVfI7vfzeiJcQdlrrpVQuxDoEjI9ZEwMrGBtqN3RM7GEaL34K6pbPpD_6eI_f4haTyr_8AMbPhRjdcC7ZhyLR44KEeyE5jBgZD746xnSB2PgYBQku7v6MOIVXWyWaIR7oLZM_72OM4cDr9_nnA/s1600/omnidevs_comic5.jpg" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" border="0" data-original-height="2480" data-original-width="3508" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_Y8Wnrm-rvAHnDlP3Ozjxx_ehIivrrkowdbHMspyHCVfI7vfzeiJcQdlrrpVQuxDoEjI9ZEwMrGBtqN3RM7GEaL34K6pbPpD_6eI_f4haTyr_8AMbPhRjdcC7ZhyLR44KEeyE5jBgZD746xnSB2PgYBQku7v6MOIVXWyWaIR7oLZM_72OM4cDr9_nnA/s1600/omnidevs_comic5.jpg"/>
</a>
</div>
<p>
<a href="https://i.imgur.com/AX6cFoZ.jpg">Even larger version</a>
</p>
<p>
Stay tuned for the next instalment!</p>
<p>
Previous strip: <a href="https://arjan-tijms.omnifaces.org/2020/09/hiring-right-people.html">Hiring the right people
</a> Next Strip: <a href="https://arjan-tijms.omnifaces.org/2022/12/close-them-out.html">Close them out!
</a>
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-58399176942673457912022-10-03T08:41:00.001-07:002022-10-03T08:41:44.675-07:00Jakarta EE Survey 2022At OmniFaces we poll the community from <a href="http://arjan-tijms.omnifaces.org/2015/03/the-most-popular-java-ee-servers-in.html">time</a> to <a href="https://arjan-tijms.omnifaces.org/2018/03/java-ee-survey-2018.html">time</a> and <a href="https://arjan-tijms.omnifaces.org/2020/09/jakarta-ee-survey-2020.html">again</a> about Jakarta EE (previously Java EE) and related technologies.
<p>
With the <a href="https://blogs.oracle.com/javamagazine/transition-from-java-ee-to-jakarta-ee" target="_blank">transfer of Java EE to Jakarta EE</a> now fully completed and <a href="https://jakarta.ee/news/jakarta-ee-10-released">Jakarta EE 10 released</a>, people are now <a href="https://docs.google.com/document/d/1m-dkvbL0iFFzitO4vt1SVq6GGSJyFdCDM2NU_FzGS10/edit" target="_blank">starting to think about Jakarta EE 11</a>, the second Jakarta EE feature release. As such it's a good time to poll the community again. This year we're doing so in cooperation with <a href="https://omnifish.ee">OmniFish</a>.
<p>
In the 2022 edition, there are 4 categories of questions again:
<ul>
<li>Current usage of Jakarta EE</li>
<li>Servlet containers</li>
<li>APIs related to Jakarta EE</li>
<li>The future of Jakarta EE</li>
</ul>
<p>
Compared to 2020, we simplified some of the questions once more; again omitting some of the less popular options to make it more manageable. We kept the questions about the future of Jakarta EE and MP together as this issue still isn't resolved. We also ask about the preferred Jakarta EE cadence. As Jakarta EE 10 is the first feature release, we haven't really established a cadence yet. EE 10 however was released 1 year and 4 months after <a href="https://eclipse-ee4j.github.io/jakartaee-platform/jakartaee9/JakartaEE9.1ReleasePlan">Jakarta EE 9.1</a>. The plan was for 1 year, but some issues with particularly the Concurrency TCK pushed it out.
<p>
Jakarta EE 10 is as mentioned the first feature release, and is generally well received, but in order to keep up the pace it's still very important that we know what matters to all of its users out there.
<p>
So therefor we'd like to invite all Jakarta EE users to participate in
<b><a href="https://surveymonkey.com/r/jakarta2022-omni">The Jakarta EE Survey 2022</a></b>Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-58755094616674916642022-04-04T18:04:00.001-07:002022-04-04T18:04:24.929-07:00What’s new in Jakarta Security 3?Despite the version number 3, Jakarta Security 3 is the first real update of <a href="https://jakarta.ee/specifications/security/2.0/jakarta-security-spec-2.0" target="_blank">Jakarta Security</a> since it was introduced as <a href="https://jcp.org/en/jsr/detail?id=375" target="_blank">Java EE Security</a> in Java EE 8.
<p>
In this article we’ll take a look at what new things have been added. We’ll first take a look at the user facing umbrella API, which is Jakarta Security itself, and then take a look at the two underlying SPIs it depends on; Jakarta Authentication and Jakarta Authorization.
<p>
<h2>OpenID Connect</h2>
The signature addition to Jakarta Security 3 is the new OpenID Connect authentication mechanism, contributed by Payara’s Lead Developer <a href="https://twitter.com/rdebusscher" target="_blank">Rudy De Busscher</a> and Principal Engineer <a href="https://twitter.com/jGauravGupta" target="_blank">Gaurav Gupta</a>.
<p>
OpenID Connect joins the existing <a href="https://github.com/jakartaee/security/blob/master/api/src/main/java/jakarta/security/enterprise/authentication/mechanism/http/BasicAuthenticationMechanismDefinition.java#L26" target="_blank">Basic</a>, <a href="https://github.com/jakartaee/security/blob/master/api/src/main/java/jakarta/security/enterprise/authentication/mechanism/http/FormAuthenticationMechanismDefinition.java#L27" target="_blank">Form</a> and <a href="https://github.com/jakartaee/security/blob/master/api/src/main/java/jakarta/security/enterprise/authentication/mechanism/http/CustomFormAuthenticationMechanismDefinition.java" target="_blank">Custom Form</a> authentication mechanisms. The plan to also gain parity to Servlet by adding Jakarta Security versions of the <a href="https://github.com/jakartaee/security/issues/120" target="_blank">Client-Cert</a> and <a href="https://github.com/jakartaee/security/issues/190" target="_blank">Digest</a> authentication mechanisms unfortunately failed, as simply nobody picked up the work for that. As Jakarta Security is now mostly a volunteer driven OSS project, that’s of-course how things go; we can plan whatever we want, but are ultimately dependent on volunteers picking up things.
<p>
OpenID Connect itself is a mechanism where a third party server takes care of the actual authentication of an end-user, and the result of this authentication is then communicated back to our server. “Our server” here is the one that runs Jakarta Security to secure our web application. Since we rely on a third party server, that remote OpenID Connect server is called a “relying party” in the OpenID Connect terminology.
<p>
This is depicted in the following slightly adjusted diagram from the OpenID Connect website:
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&family=Waiting+for+the+Sunrise&display=swap');
</style>
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
+--------+ +--------+
| | | |
| |---------------(1) Authentication Request------------->| |
| | | |
| | +--------+ | |
| | | End- |<--(2) Authenticates the End-User---->| |
| RP | | User | | OP |
| | +--------+ | |
| | | |
| |<---------(3) Returns Authorization code---------------| |
| | | |
| |---------(3b) | |
| | | Redirect to original resource (if any) | |
| |<----------+ | |
| | | |
| |------------------------------------------------------>| |
| | (4) Request to TokenEndpoint for Access / Id Token | |
| OpenID |<------------------------------------------------------| OpenID |
| Connect| | Connect|
| Client | ----------------------------------------------------->|Provider|
| | (5) Fetch JWKS to validate ID Token | |
| |<------------------------------------------------------| |
| | | |
| |------------------------------------------------------>| |
| | (6) Request to UserInfoEndpoint for End-User Claims | |
| |<------------------------------------------------------| |
| | | |
+--------+ +--------+
</pre>
See <a href="https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth" target="_blank">openid.net/specs/openid-connect-core-1_0</a>
<p>
RP, or Relying Party, is the Jakarta EE server running our web application. OP, or the OpenID Connect Provider, is the remote server doing authentication. This can be another server that we run ourselves, or, more common, it’s a public service such as Google, Facebook, Twitter, etc.
<p>
We can use this authentication mechanism in our own applications via the new “<a href="https://github.com/jakartaee/security/blob/master/api/src/main/java/jakarta/security/enterprise/authentication/mechanism/http/OpenIdAuthenticationMechanismDefinition.java#L45" target="_blank">@OpenIdAuthenticationMechanismDefinition</a>” annotation. The following gives an example:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
<span style='color:#7f9fbf; font-weight:bold; '>@OpenIdAuthenticationMechanismDefinition(</span>
<span style='color:#7f9fbf; font-weight:bold; '>  </span>
<span style='color:#7f9fbf; font-weight:bold; '>    providerURI = "http://localhost:8081/openid-connect-server-webapp",</span>
<span style='color:#7f9fbf; font-weight:bold; '></span>
<span style='color:#7f9fbf; font-weight:bold; '>    clientId = "client",</span>
<span style='color:#7f9fbf; font-weight:bold; '></span>
<span style='color:#7f9fbf; font-weight:bold; '>    clientSecret = "secret",</span>
<span style='color:#7f9fbf; font-weight:bold; '>   </span>
<span style='color:#7f9fbf; font-weight:bold; '>    redirectURI = "${baseURL}/Callback",</span>
<span style='color:#7f9fbf; font-weight:bold; '></span>
<span style='color:#7f9fbf; font-weight:bold; '>    redirectToOriginalResource = true</span>
<span style='color:#7f9fbf; font-weight:bold; '>)</span>
</pre>
<p>
There are many more attributes that can be configured, but the above is a typical minimal configuration. Let’s quickly take a look at what the various attributes do.
<p>
The “providerURI” specifies the location of the OpenID Provider. This is where the end-user is redirected to when logging into our application. The clientId and clientSecret are essentially the username/password to identify ourselves to the OpenID Provider. Note that when the user is redirect only the clientId is put into the redirect URL. The clientSecret is used when we do our secure server to server communication which does not involve the end-user. Also note that in Jakarta Security annotation attributes can contain <a href="https://jakarta.ee/specifications/expression-language/4.0/jakarta-expression-language-spec-4.0" target="_blank">Jakarta Expression Language</a>, and in practice the clientId and clientSecret would not be put in constants in the code this way.
<p>
The redirectURI is the location the end-user is redirected back to after being authenticated. A special placeholder ${baseURL} is used here, which resolves to the actual URL our application is deployed to.
<p>
Finally we have the redirectToOriginalResource which makes sure the end-user is redirected back to the original resource (page, path) for the situation where authentication was automatically triggered when a protected resources was accessed. This works in the same way as the well-known FORM authentication mechanism works. When set to false the end-user will stay at the resource behind the redirectURI, which obviously has to exist then. If set to true, the authentication mechanism monitors it, and there doesn’t have to be an actual Servlet or Filter mapped to it.
<p>
The following shows this annotation in context on a Servlet:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
<span style='color:#7f9fbf; font-weight:bold; '>@OpenIdAuthenticationMechanismDefinition(</span>
<span style='color:#7f9fbf; font-weight:bold; '>    providerURI = "http://localhost:8081/openid-connect-server-webapp",</span>
<span style='color:#7f9fbf; font-weight:bold; '>    clientId = "client",</span>
<span style='color:#7f9fbf; font-weight:bold; '>    clientSecret = "secret",</span>
<span style='color:#7f9fbf; font-weight:bold; '>    redirectURI = "${baseURL}/Callback",</span>
<span style='color:#7f9fbf; font-weight:bold; '>    redirectToOriginalResource = true</span>
<span style='color:#7f9fbf; font-weight:bold; '>)</span>
<span style='color:#7f9fbf; font-weight:bold; '>@WebServlet("/protectedServlet")</span>
<span style='color:#7f9fbf; font-weight:bold; '>@DeclareRoles({ "foo", "bar", "kaz" })</span>
<span style='color:#7f9fbf; font-weight:bold; '>@ServletSecurity(@HttpConstraint(rolesAllowed = "foo"))</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>class</span> ProtectedServlet <span style='color:#7f0055; font-weight:bold; '>extends</span> HttpServlet {
<span style='color:#7f0055; font-weight:bold; '>private</span> <span style='color:#7f0055; font-weight:bold; '>static</span> <span style='color:#7f0055; font-weight:bold; '>final</span> <span style='color:#7f0055; font-weight:bold; '>long</span> serialVersionUID = 1L;
<span style='color:#7f9fbf; font-weight:bold; '>@Override</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>void</span> doGet(
HttpServletRequest request, HttpServletResponse response)
<span style='color:#7f0055; font-weight:bold; '>throws</span> ServletException, <span style='color:#7f0055; font-weight:bold; '>IOException</span> {
response.getWriter().write(<span style='color:#2a00ff; '>"This is a protected servlet </span><span style='color:#2a00ff; '>\n</span><span style='color:#2a00ff; '>"</span>);
}
}
</pre>
In Jakarta Security we typically combine an authentication mechanism with an identity store, which is the entity that validates the credential provided by the end-user. For OpenID Connect that end-user credential is validated by the remote OpenID Connect provider of course. We do have to validate a token coming back from the provider, but that is done internally by the OpenID Connect authentication mechanism (it does uses an identity store for this, but an internal one).
<p>
However, a public OpenID Provider typically has no knowledge of groups an end-user has in our application, so we do have to provide an identity store for exactly that purpose. This is basically the same thing as we often have to do for client-cert authentication, as the certificates don’t contain any groups either. The following gives an example of such store:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
<span style='color:#7f9fbf; font-weight:bold; '>@ApplicationScoped</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>class</span> AuthorizationIdentityStore <span style='color:#7f0055; font-weight:bold; '>implements</span> IdentityStore {
<span style='color:#7f0055; font-weight:bold; '>private</span> <span style='color:#7f0055; font-weight:bold; '>Map</span><<span style='color:#7f0055; font-weight:bold; '>String</span>, <span style='color:#7f0055; font-weight:bold; '>Set</span><<span style='color:#7f0055; font-weight:bold; '>String</span>>> authorization =
<span style='color:#7f0055; font-weight:bold; '>Map</span>.of(<span style='color:#2a00ff; '>"user"</span>, <span style='color:#7f0055; font-weight:bold; '>Set</span>.of(<span style='color:#2a00ff; '>"foo"</span>, <span style='color:#2a00ff; '>"bar"</span>));
<span style='color:#7f9fbf; font-weight:bold; '>@Override</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>Set</span><ValidationType> validationTypes() {
<span style='color:#7f0055; font-weight:bold; '>return</span> <span style='color:#7f0055; font-weight:bold; '>EnumSet</span>.of(PROVIDE_GROUPS);
}
<span style='color:#7f9fbf; font-weight:bold; '>@Override</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>Set</span><<span style='color:#7f0055; font-weight:bold; '>String</span>> getCallerGroups(CredentialValidationResult result) {
<span style='color:#7f0055; font-weight:bold; '>return</span> authorization.get(result.getCallerPrincipal().getName());
}
}
</pre>
In the example store above we map an end-user called “user” to the groups “foo” and “bar”. This identity store will be called together with the internal OpenID Connect identity store, and the job our one here is to provide just the groups.
<p>
These two classes together can be packaged up and constitute a full application that we can use to test. It’s available as a Maven project here: <a href="https://github.com/jakartaee/security/tree/master/tck/app-openid3" target="_blank">app-openid3</a>
<h2>Small API enhancements</h2>
Next to the ticket feature OpenID Connect, a number of small API enhancements have been added:
<h3>CallerPrincipal Serializable</h3>
<p>
The native Principal type that Jakarta Security uses to denote the caller principal, was not serializable in the first versions. This caused various problems when this principal was stored in an HTTP session, and some kind of fail-over or clustering was used. It’s now Serializable:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
<span style='color:#3f5fbf; '>/**</span>
<span style='color:#3f5fbf; '> </span><span style='color:#7f9fbf; font-weight:bold; '>*</span><span style='color:#3f5fbf; '> Principal that represents the caller principal associated with the invocation </span>
<span style='color:#3f5fbf; '> </span><span style='color:#7f9fbf; font-weight:bold; '>*</span><span style='color:#3f5fbf; '> being processed by the container (e</span><span style='color:#3f5fbf; '>.</span><span style='color:#3f5fbf; '>g. the current HTTP request).</span>
<span style='color:#3f5fbf; '> */</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>class</span> CallerPrincipal <span style='color:#7f0055; font-weight:bold; '>implements</span> Principal, Serializable {
</pre>
<h3>Dynamically adding interceptor to a build-in CDI bean</h3>
Jakarta Security provides a number of interceptors that add functionality to a bean, mostly beans that are authentication mechanisms. Those are easy to add to one’s own beans, but take <a href="https://arjan-tijms.omnifaces.org/2017/08/dynamically-adding-interceptor-to-build.html" target="_blank">somewhat more work</a> to apply to one of the authentication mechanisms that are build in to Jakarta Security.
<p>
Two of the artefacts that needed to be created for this to work were a wrapper for the HttpAuthenticationMechanism type, and an annotation literal for the interceptor that we wanted to add dynamically.
<p>
This task has been made a little bit easier in Jakarta Security 3, where all Interceptors now have default annotation literals, and the <a href="https://github.com/jakartaee/security/blob/master/api/src/main/java/jakarta/security/enterprise/authentication/mechanism/http/HttpAuthenticationMechanismWrapper.java" target="_blank">HttpAuthenticationMechanismWrapper</a> type is provided by the API now.
<p>
For example:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
<span style='color:#7f9fbf; font-weight:bold; '>@Inherited</span>
<span style='color:#7f9fbf; font-weight:bold; '>@InterceptorBinding</span>
<span style='color:#7f9fbf; font-weight:bold; '>@Retention(RUNTIME)</span>
<span style='color:#7f9fbf; font-weight:bold; '>@Target(TYPE)</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f9fbf; font-weight:bold; '>@interface</span> AutoApplySession {
<span style='color:#3f5fbf; '>/**</span>
<span style='color:#3f5fbf; '>     </span><span style='color:#7f9fbf; font-weight:bold; '>*</span><span style='color:#3f5fbf; '> Supports inline instantiation of the AutoApplySession annotation.</span>
<span style='color:#3f5fbf; '>     </span><span style='color:#7f9fbf; font-weight:bold; '>*</span><span style='color:#3f5fbf; '></span>
<span style='color:#3f5fbf; '>     </span><span style='color:#7f9fbf; font-weight:bold; '>*</span><span style='color:#3f5fbf; '> </span><span style='color:#7f9fbf; font-weight:bold; '>@since</span><span style='color:#3f5fbf; '> </span><span style='color:#3f5fbf; '>3.0</span><span style='color:#3f5fbf; '></span>
<span style='color:#3f5fbf; '>     */</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>static</span> <span style='color:#7f0055; font-weight:bold; '>final</span> <span style='color:#7f0055; font-weight:bold; '>class</span> Literal <span style='color:#7f0055; font-weight:bold; '>extends</span> AnnotationLiteral<AutoApplySession>
<span style='color:#7f0055; font-weight:bold; '>implements</span> AutoApplySession {
<span style='color:#7f0055; font-weight:bold; '>private</span> <span style='color:#7f0055; font-weight:bold; '>static</span> <span style='color:#7f0055; font-weight:bold; '>final</span> <span style='color:#7f0055; font-weight:bold; '>long</span> serialVersionUID = 1L;
<span style='color:#3f5fbf; '>/**</span>
<span style='color:#3f5fbf; '>         </span><span style='color:#7f9fbf; font-weight:bold; '>*</span><span style='color:#3f5fbf; '> Instance of the {</span><span style='color:#7f9fbf; font-weight:bold; '>@</span><span style='color:#3f5fbf; '>link AutoApplySession} Interceptor Binding.</span>
<span style='color:#3f5fbf; '>         */</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>static</span> <span style='color:#7f0055; font-weight:bold; '>final</span> Literal INSTANCE = <span style='color:#7f0055; font-weight:bold; '>new</span> Literal();
}
}
</pre>
<h2>Jakarta Authentication</h2>
<a href="https://jakarta.ee/specifications/authentication/2.0/jakarta-authentication-spec-2.0" target="_blank">Jakarta Authentication</a> is the underlying SPI on which Jakarta Security depends. Enhancements here mostly benefit library vendors, although some advanced users can opt to direct use it as well.
<h3>Register ServerAuthModule</h3>
The end user of Jakarta Authentication, as well as integrators such as Jakarta Security implementations almost always just care about registering a ServerAuthModule. Yet the AuthConfigFactory only accepts an AuthConfigProvider, which is essentially a “wrapper-wrapper-wrapper-wrapper” of a ServerAuthModule to the end user. A <a href="https://github.com/jakartaee/authentication/blob/master/api/src/main/java/jakarta/security/auth/message/config/AuthConfigFactory.java#L398" target="_blank">new method</a> has been added to the AuthConfigFactory to only register a ServerAuthModule.
<p>
A ServerAuthModule is typically installed in a servlet listener. The following is an example:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
<span style='color:#7f9fbf; font-weight:bold; '>@WebListener</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>class</span> SamAutoRegistrationListener <span style='color:#7f0055; font-weight:bold; '>implements</span> ServletContextListener {
<span style='color:#7f9fbf; font-weight:bold; '>@Override</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>void</span> contextInitialized(ServletContextEvent sce) {
AuthConfigFactory
.getFactory()
.registerServerAuthModule(
<span style='color:#7f0055; font-weight:bold; '>new</span> TestServerAuthModule(),
sce.getServletContext());
}
}
</pre>
<h3>Add missing generics to API</h3>
<p>
Jakarta Authentication has curiously been at Java SE 1.4 even in Jakarta EE 9.1, which officially targets Java SE 8 and 11. This specifically meant a lot of generics were missing everywhere in the API. These have now been added. For example:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>interface</span> ServerAuthModule <span style='color:#7f0055; font-weight:bold; '>extends</span> ServerAuth {
<span style='color:#7f0055; font-weight:bold; '>void</span> initialize(
MessagePolicy requestPolicy, MessagePolicy responsePolicy,
CallbackHandler handler, <span style='color:#7f0055; font-weight:bold; '>Map</span><<span style='color:#7f0055; font-weight:bold; '>String</span>, <span style='color:#7f0055; font-weight:bold; '>Object</span>> options)
<span style='color:#7f0055; font-weight:bold; '>throws</span> AuthException;
<span style='color:#7f0055; font-weight:bold; '>Class</span><?>[] getSupportedMessageTypes();
}
</pre>
<h3>Add default methods</h3>
A ServerAuthModule requires methods for “secureResponse” and “cleanSubject” to be implemented, but by far not all ServerAuthModules need to do something there. For these methods defaults have been added, so implementations that don’t need those can be a little less verbose. The interface now looks as follows:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>interface</span> ServerAuth {
AuthStatus validateRequest(
MessageInfo messageInfo, Subject clientSubject,
Subject serviceSubject) <span style='color:#7f0055; font-weight:bold; '>throws</span> AuthException;
<span style='color:#7f0055; font-weight:bold; '>default</span> AuthStatus secureResponse(
MessageInfo messageInfo, Subject serviceSubject)
<span style='color:#7f0055; font-weight:bold; '>throws</span> AuthException {
<span style='color:#7f0055; font-weight:bold; '>return</span> AuthStatus.SEND_SUCCESS;
}
<span style='color:#7f0055; font-weight:bold; '>default</span> <span style='color:#7f0055; font-weight:bold; '>void</span> cleanSubject(
MessageInfo messageInfo, Subject subject)
<span style='color:#7f0055; font-weight:bold; '>throws</span> AuthException {
}
}
</pre>
<h3>Add constructor taking cause to AuthException</h3>
Jakarta Authentication being at Java SE 1.4 level meant its AuthException didn’t make use of setting the exception cause that was added in Java SE 5.
<p>
Throwing an exception from Jakarta Authentication code was therefor more than a little verbose:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
throw (AuthException) new AuthException().initCause(e);
</pre>
New constructors have been added now taking a cause, so that we can now do:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
throw new AuthException(e);
</pre>
<h3>Distinguish between invocation at start of request and invocation following authenticate()</h3>
In the Servlet Container Profile of Jakarta Authentication a ServerAuthModule can be called by the container at the start of a request (before Filters and Servlets are invoked) or following a call to HttpServletRequest.authenticate(). For a ServerAuthModule there’s no way to distinguish between those two cases, which is sometimes needed for more advanced interactions.
<p>
A ServerAuthModule can now check this by looking at the `jakarta.servlet.http.isAuthenticationRequest` key in the message info map.
<h2>Jakarta Authorization</h2>
<a href="https://jakarta.ee/specifications/authorization/2.0/authorization-spec-2.0" target="_blank">Jakarta Authorization</a> is another underlying SPI on which Jakarta Security depends. Enhancements here too mostly benefit library vendors, although some advanced users can opt to direct use it as well.
<h3>Add getPolicyConfiguration methods without state requirement</h3>
The PolicyConfigurationFactory in Jakarta Authorization has methods to retrieve a policy configuration instance, which hold a collection of permissions which are used for authorization decisions.
A Policy (authorization module) can however not easily use these, as all the existing methods have required side effects. In practice such Policy therefor needs to resort to implementation specific ways, often strongly coupling the PolicyConfigurationFactory and Policy.
For the new release methods have been added to get that PolicyConfiguration directly without any side effects;
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>abstract</span> PolicyConfiguration getPolicyConfiguration(String contextID);
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>abstract</span> PolicyConfiguration getPolicyConfiguration();
</pre>
The first variant can be used when the Policy already has the contextID (an identifier for the application), while the second variant is a convenient method that returns the PolicyConfiguration for the contextID that’s set on the calling thread.
<h3>Add methods to PolicyConfiguation to read permissions</h3>
The PolicyConfiguration as mentioned above stores the permissions, but curiously enough didn’t contain methods before to read these permissions back. A Policy always needed to resort to implementation specific methods to obtain these permissions. For instance, in old versions of GlassFish the PolicyConfiguration would write its permissions to a policy file on disk first, and then the Policy would read that file back.
Now finally some methods have been added to directly read back the permissions:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
Map<String, PermissionCollection> getPerRolePermissions();
PermissionCollection getUncheckedPermissions();
PermissionCollection getExcludedPermissions();
</pre>
<h3>Generic return value for getContext</h3>
Jakarta Authorization has a PolicyContext object from which instances of various types can be obtained, most importantly the Subject.
The signature of this method returned an Object before, so that a cast was always needed. In the new version this has been changed to a generic return value:
public static <T> T getContext(String key) throws PolicyContextException
So for example previously one did:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
Subject subject =
(Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
</pre>
Which can now be:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'>
Subject subject = PolicyContext.getContext(“javax.security.auth.Subject.container");
</pre>
<h2>Final thoughts</h2>
The amount of changes for Jakarta Security 3 is smaller than planned, but the big ticket feature OpenID Connect is very welcome. It was planned for the initial release, and some implementations had started, but ultimately didn’t make it in back then. The changes in the lower level SPIs are small, but some of them quite important.
Looking forward, the next version of Jakarta Security should focus more on the authorization topic. Authorization modules are still somewhat of an obscure thing in the current API, which is shame, as it's a very powerful concept. This update has set the stage for a more accessible future API there.
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&family=Waiting+for+the+Sunrise&display=swap');
</style>
<p style="font-family: 'Waiting for the Sunrise', cursive; font-size: 150%">
<i>Arjan Tijms</i>
</p>Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com1tag:blogger.com,1999:blog-4498889353428710313.post-72811073967833245632021-12-09T05:01:00.001-08:002022-01-14T16:09:56.604-08:00GlassFish at Eclipse - JakartaOne slidesDuring the <a href="https://jakartaone.org/2021">JakartaOne livestream 2021</a> I talked about GlassFish at Eclipse, which was a great experience with close to 900 people online.
<p>
Thank you all for watching. These are the slides used during the presentation:
<p>
<iframe src="https://drive.google.com/file/d/1xHU_VlWTNtmOUPT9Yr1PMQIhIDAmXqXw/preview" width="800" height="480"></iframe>
<p>
And this is the presentation itself:
<div class="separator" style="clear: both; text-align: center;"><iframe class="BLOG_video_class" allowfullscreen="" youtube-src-id="3EiPRbjteug" width="800" height="480" src="https://www.youtube.com/embed/3EiPRbjteug"></iframe></div>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&family=Waiting+for+the+Sunrise&display=swap');
</style>
<p style="font-family: 'Waiting for the Sunrise', cursive; font-size: 150%">
<i>Arjan Tijms</i>
</p>
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com1tag:blogger.com,1999:blog-4498889353428710313.post-26453433321411409732021-11-24T13:30:00.000-08:002021-11-24T13:30:25.167-08:00JakartaOne Livestream on 7 Dec 2021Happy to announce I'll be speaking at the biggest Jakarta EE event of the year, which is the JakartaOne Livestream.
<div class="separator" style="clear: both;"><a href="https://pbs.twimg.com/media/FE4VMVJXEAQ7lwx?format=jpg&name=medium" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="450" data-original-width="800" src="https://pbs.twimg.com/media/FE4VMVJXEAQ7lwx?format=jpg&name=medium"/></a></div>
Register now by using the following link: <a href="https://jakartaone.org/2021">jakartaone.org/2021</a> and be sure not to miss out!
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-36213426484376181252021-04-08T09:13:00.001-07:002021-04-08T09:13:53.238-07:00GlassFish now runs on JDK 16!<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&family=Waiting+for+the+Sunrise&display=swap');
</style>
<a href="https://glassfish.org" target="_blank">GlassFish</a>, an open source Jakarta EE Platform implementation, is a code base that goes back a long time, in essence all the way back to 1996. It's also a fairly large code base. Therefor it's not suprising perhaps that in all that time, it obtained some cruft between all those lines of code, which made it challenging to run on modern versions of the JDK.
<p>
The last few months or so the GlassFish team has been working on removing this cruft, and making the release compatible with newer JDK versions. The primary target was to be able to compile the code with JDK 11 and be able to run it on that as well. A stretch goal was to have it compiling with- and running on JDK 16 too. As of <a href="https://github.com/eclipse-ee4j/glassfish/pull/23446" target="_blank">PR 23446</a> we have now reached this goal:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSofSYPgwJXBUb748adJb_lzBzM-rwFQau0gp5iWd4QoKazoCEIw3JUExSKdMtnXosp3NoIqWT5jKMXeb4Gue8jFQOydTXwgdBICcxnrERcLmpfqL80C_ilMoePiTKtL0WLqVnVHoB1iRa/s0/glassfish_jdk16.png" style="display: block; padding: 1em 0; text-align: center; "><img width="700" alt="GlassFish JDK 16 all tests green" border="0" data-original-height="1078" data-original-width="2048" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSofSYPgwJXBUb748adJb_lzBzM-rwFQau0gp5iWd4QoKazoCEIw3JUExSKdMtnXosp3NoIqWT5jKMXeb4Gue8jFQOydTXwgdBICcxnrERcLmpfqL80C_ilMoePiTKtL0WLqVnVHoB1iRa/s0/glassfish_jdk16.png"/></a></div>
Note that it concerns a nightly of a not-yet merged PR, and that the official certification of the <a href="https://projects.eclipse.org/projects/ee4j.glassfish/releases/6.1.0" target="_blank">soon to be released GlassFish 6.1.0</a> will be done against JDK 11 only (since, for now, <a href="https://github.com/eclipse-ee4j/jakartaee-tck">the Jakarta EE TCK</a> only runs on JDK 11). The internal tests touch a lot of functionality in GlassFish, but of course not everything.
<p>
Yet, this is a major milestone nevertheless. Thanks to everyone involved who helped to make this happen!
<p style="font-family: 'Waiting for the Sunrise', cursive; font-size: 150%">
<i>Arjan Tijms</i>
</p>
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-73961936542709438452021-03-25T10:40:00.001-07:002021-03-25T10:40:25.637-07:00The CN4J profile as the common EE and MP profile - a proposal<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&family=Waiting+for+the+Sunrise&display=swap');
</style>
The Java EE platform was moved a while ago to <a href="https://blogs.oracle.com/javamagazine/transition-from-java-ee-to-jakarta-ee">become the Jakarta EE platform</a>. At about the same time, a group of Java EE vendors split off and started MicroProfile; a platform that initially only contained a number of Java EE APIs, but was later on extended with APIs that were <a href="https://blogs.oracle.com/theaquarium/java-ee-8-community-survey-results-and-next-steps">originally planned for Java EE 8</a> (such as Config, Health, and JWT).
<p>
With MicroProfile and Jakarta EE now both at Eclipse, and both including approximately all of the same vendors again, there has been an increasing demand for somehow joining the efforts. We asked about this in our recent survey, where most repsondends would <a href="https://arjan-tijms.omnifaces.org/2021/02/jakarta-ee-survey-20202021-results.html#ee-mp-groups">like to see them aligned</a>.
<p>
This begs the question of how to do this exactly. MicroProfile is already using Jakarta EE APIs, and there's a strong desire to use MicroProfile Config in Jakarta EE. This would result in a circular dependency though, which is, perhaps, not ideal. One option in software engineering to break circular dependencies is to factor out the common dependencies into a new, shared, module.
<p>
Factoring out the Jakarta APIs that MicroProfile uses, and the MicroProfile API that Jakarta wants to use, would paint a picture such as this:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9v_2Lj1gnIzg8yzrtwBQ9pzgqfQuRPN_Lzpt6JTpR8NunzW3p1SSMaDl4PruGSvJURsv99TS7IQmFAaKyPd2fk5QjuDLda6h-Va4zDeA_CwM5wHMujNvbFlEc3N0Bu7ZSX84x02AI4IOT/s0/cn4j_profile.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="CN4J Profile" width="845" border="0" data-original-height="2048" data-original-width="1690" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9v_2Lj1gnIzg8yzrtwBQ9pzgqfQuRPN_Lzpt6JTpR8NunzW3p1SSMaDl4PruGSvJURsv99TS7IQmFAaKyPd2fk5QjuDLda6h-Va4zDeA_CwM5wHMujNvbFlEc3N0Bu7ZSX84x02AI4IOT/s0/cn4j_profile.png"/></a></div>
At the top we see the CN4J profile, where CN4J stands for Cloud Native for Java. This is the name of the alliance created to align MicroProfile. All the APIs in this profile would take into consideration that they are used by both MicroProfile and Jakarta EE, and hence would evolve accordingly.
<p>
To the left we see the current MicroProfile APIs that are part of the MicroProfile platform, and are all exclusive to MicroProfile. Similarly to the right we see a selection of the Jakarta EE Web Profile APIs <i>(some dependencies of several APIs, such as Authentication and Interceptors are left out)</i>.
<p>
In the future some additional APIs could move to the CN4J profile, but obviously this should not be too many. At the moment Jakarta Security is a candidate (in practice, @RolesAllowed/JWT is not rarely based on Jakarta Security).
<p>
Do note that the above is a personal proposal, and while discussed, is in no way endorsed by either the MicroProfile or Jakarta EE working groups, or the CN4J alliance. It's intended as an idea to base further discussion on.
<p style="font-family: 'Waiting for the Sunrise', cursive; font-size: 150%">
<i>Arjan Tijms</i>
</p>
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-23618950463155500002021-02-21T15:53:00.005-08:002021-02-21T16:35:03.358-08:00Jakarta EE Survey 2020/2021 - results<a href="https://arjan-tijms.omnifaces.org/2020/09/jakarta-ee-survey-2020.html">Last September</a> we conducted our survey about Jakarta EE.
<p>
In this survey we asked several questions about Jakarta EE, what people use exactly, and what they would like to see next. The survey was promoted in October, after which we got about 500 responses. The survey was left alone for the next months, until a little promotion was done in February, resulting in about 100 extra responses. In total we ended up with <b>684 respondents</b> in total, which is down from the 1054 we got <a href="https://arjan-tijms.omnifaces.org/2018/05/java-ee-survey-2018-results.html">last time</a>.
<p>
Looking at the results we must keep in mind that surveys like this are by definition biased; the respondents are self-selected, and come from the pool of places that we (OmniFaces) reach. These are <a href="https://omnifaces.org">our own website</a>, <a href="https://twitter.com/OmniFaces">our Twitter account</a>, <a href="https://newsroom.eclipse.org/news/community-news/jakarta-ee-survey-2020-omnifaces" target="_blank">the Jakarta EE news section</a>, etc. The results may therefore be biased towards the more active OSS developer.
<p>
Overview of questions
<small>
<ol>
<li> <a href="#versions">Which versions of Java EE/Jakarta EE have you recently used? </a> </li>
<li> <a href="#servers">Which application servers have you recently used? </a> </li>
<li> <a href="#servers-rating">How would you rate the application servers that you've used? </a> </li>
<li> <a href="#apis">Which Java EE/Jakarta EE APIs have you used recently? </a> </li>
<li> <a href="#servlet-used">Have you used a (standalone) Servlet container recently? </a> </li>
<li> <a href="#servlet-which">Which Servlet containers have you used recently? </a> </li>
<li> <a href="#ee-in-war">Which additional Java EE/Jakarta EE libraries do you use with your Servlet container? </a> </li>
<li> <a href="#ee-in-war-number">On average, how many Java EE/Jakarta EE libraries do you add when using a Servlet container? </a> </li>
<li> <a href="#mp-apis-used">Have you used MicroProfile APIs recently? </a> </li>
<li> <a href="#mp-products">Which MicroProfile products have you used recently? </a> </li>
<li> <a href="#mp-apis-which">Which MicroProfile APIs have you used recently? </a> </li>
<li> <a href="#ee-mp-groups">What's your preferred situation regarding MicroProfile vs Jakarta EE? </a> </li>
<li> <a href="#ee-mp-products">What Jakarta EE and MicroProfile products do you prefer? </a> </li>
<li> <a href="#ee-alt-known">Which of the following products that support one or more Jakarta EE APIs, but are not traditional or certified EE application servers, have you heard of? </a> </li>
<li> <a href="#ee-cadence">What would be the ideal cadence (time between major releases) for Jakarta EE? </a> </li>
<li> <a href="#javax-jakarta">Knowing that Jakarta EE 9 contains only the javax to jakarta namespace change, do you: </a> </li>
<li> <a href="#ee-apis-update">Which APIs would you most like to see updated in the next version of Jakarta EE? </a> </li>
<li> <a href="#ee-improve-general">How important are the following general options to improve Jakarta EE? </a> </li>
<li> <a href="#ee-improve-specific">How important are the following more specific options to improve Jakarta EE? </a> </li>
<li> <a href="#comments">Do you have any final comments on how Jakarta EE can be improved in the future? </a> </li>
</ol>
</small>
<p>
Let's take a look at the results from this year with the first question:
<a name="versions"></a>
<h2>Question 1 - Which versions of Java EE/Jakarta EE have you recently used?</h2>
We previewed this question <a href="https://arjan-tijms.omnifaces.org/2021/01/jakarta-ee-2020-survey-which-ee.html">recently</a>. Compared to then the percentages didn't change:
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdj7rB24tW2NzG8aLZB4cBVQcLFR7wevSV0uIaX-qMx59G-NrNuT6uNdHVISr50XFROMnCSZQk8Ob7FIMfO6l2ca5t4i0t6qKxYhI6w0PMAY16Gcu3bW9S7XgmXDmmvokSJvbCIcqEB2rg/s0/question1_2020.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" width="623" border="0" data-original-height="852" data-original-width="1246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdj7rB24tW2NzG8aLZB4cBVQcLFR7wevSV0uIaX-qMx59G-NrNuT6uNdHVISr50XFROMnCSZQk8Ob7FIMfO6l2ca5t4i0t6qKxYhI6w0PMAY16Gcu3bW9S7XgmXDmmvokSJvbCIcqEB2rg/s0/question1_2020.png"/></a>
</div>
In the 2018 survey we asked a very similar question "Which versions of Java EE have you recently (last couple of months) used?"
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/2.svg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" width="623" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/2.svg"/></a>
</div>
Not entirely surprisingly but still good to see confirmed is that Jakarta EE 8 and Java EE 8 usage has gone up, with Java EE 7 usage decreased. Considering that Jakarta EE 8 and Java EE 8 are functionality identical it's interesting to see that they both add up to 74% (taking into accounts duplicates). With Java EE 7 at 35% in 2020, it means Java EE and "EE 8" have almost exactly swapped places.
<p><br /></p>
<a name="servers"></a>
<h2>Question 2 - Which application servers have you recently used?</h2>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi30Qqad5eZew8o7DmcnuEoWvP3VESdEhkWDubbqJ7c-xnfNm60howjSmr7cZjTjR7nxynqXoLvaK7Va5OcibGIxePiffUqljFGlkV6geRmewEoIpRgDCbvyyLnm0sJ4bR2x1olxpvqElWz/s0/question2_2020.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" border="0" width="623" data-original-height="1790" data-original-width="1194" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi30Qqad5eZew8o7DmcnuEoWvP3VESdEhkWDubbqJ7c-xnfNm60howjSmr7cZjTjR7nxynqXoLvaK7Va5OcibGIxePiffUqljFGlkV6geRmewEoIpRgDCbvyyLnm0sJ4bR2x1olxpvqElWz/s0/question2_2020.png"/></a>
</div>
We see here that Red Hat's <a href="https://wildfly.org" target="_blank">WildFly</a> is head and shoulders above the competition. <a href="https://payara.fish" target="_blank">Payara Server</a> is however coming in at the second place among the developers in our target audience. GlassFish comes in at the third place.
<p>
It must be noted that Payara Server is a fork of GlassFish, and despite Payara slowly putting more distance between itself and GlassFish (by for instance using a different embedded database, a different default clustering solution, and incorporating their own developed MP components) they still share an overwhelming amount of code. Essentially Payara Server and GlassFish are in the same family.
<p>
Additionally, though marketed as two products, WildFly and <a href="https://developers.redhat.com/products/eap" target="_blank">JBoss EAP</a> share the same codebase and are <a href="http://mastertheboss.com/jboss-server/jboss-eap/what-is-the-difference-between-jboss-eap-wildfly-and-jboss-as" target="_blank">technically more or less identical</a> (representing different points in time on the overal line of code).
<p>
The above means that <a href="https://tomee.apache.org" target="_blank">TomEE</a> as a server family comes in third.
Here too, we asked a similar question in 2018. Then the results were as follows:
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/3.svg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" width="623" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/3.svg"/></a>
</div>
We see here that WildFly and JBoss EAP are now mostly at the same position as they were in 2018, but relatively speaking lost a little bit of ground. GlassFish however lost a lot of ground, going from 37% to 22%. Payara Server stayed exactly where it was 2~3 years ago, at 27%.
<p>
Once the two most dominant application servers, <a href="https://www.oracle.com/middleware/technologies/weblogic-server-downloads.html" target="_blank">WebLogic</a> and Websphere have gone back further to 10% resp. 8%. <a href="https://openliberty.io" target="_blank">Open Liberty</a> gained almost exactly what Websphere has lost, going from 8% to 11%. Though we can't tell from this survey, it's not unthinkable an amount of WebSphere users moved from WebSphere to Open Liberty as those two are both from IBM.
<p><br /></p>
<a name="servers-rating"></a>
<h2>Question 3 - How would you rate the application servers that you've used?</h2>
For this question respondents could rate the servers they've used using 5 categories. There were two negative ones: "Hate it" and "Don't like it", a neutral one: "It does the job, but that's all", and two positive ones "Like it" and "Love it". The outcome has different aspects that we'll be looking at individually. Note that the servers that weren't effectively used by anyone are left out.
<p>
As the chart with all results in it looks rather crowded, let's first take a look at one with the two extreme emotions "Love it" and "Hate it" in it. The "Like it" is also added for connection with the next graph.
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh7VkGTUaNwm4qUIdGun6YdKSSNsts2r2b8M3T6boPEU9YMUvkfvo6COIMEXgvVqS5Di-dHY1H6eCga94g1G-bzNjVHDNAJmcgUGyjIAO4CfwrfA11ziyQAq1lIUrLPJf7Af8nwSLFb_Y5/s0/question3.1.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" width="774" border="0" data-original-height="1408" data-original-width="1548" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh7VkGTUaNwm4qUIdGun6YdKSSNsts2r2b8M3T6boPEU9YMUvkfvo6COIMEXgvVqS5Di-dHY1H6eCga94g1G-bzNjVHDNAJmcgUGyjIAO4CfwrfA11ziyQAq1lIUrLPJf7Af8nwSLFb_Y5/s0/question3.1.png"/>
</a>
</div>
Here too WildFly wins the popular vote, with 33% of its users in our survey claiming to love it. Payara Server is close on its heels though with 31% of its users loving it. Note that the percentage is relative to the server in question. Since WildFly is more used than Payara Server, the absolute amount of people loving WildFly is about double that of those loving Payara Server.
<p>
Like in 2018, there's little hate for most servers, with the notable exception of WebSphere and to some lesser degree WebLogic. Maybe it's not a coincidence that those two are the only closed source servers used.
<p>
Let't take a quick look at the 2018 "Love it" results again to compare:
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/4-love.svg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" width="774" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/4-love.svg"/></a>
</div>
We see that WildFly has stayed about as popular among its own users, with only a small decline. Payara Server however saw a large decline from 46% of its users loving it, to 31%. Still a good number, but clearly less. TomEE has declined somewhat, with GlassFish staying about the same, declining only a single percentage point. Surprisingly, the only server gaining in love has been JBoss EAP, going from 18% to 22%.
<p>
Let's now take a look at the graph with the less extreme emotions "Like it" and "Don't like it" and the neutral "Does the job".
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8zRW1_hH3qExlwjtSNYvQoPdsMeTiHuDYafafmRIgsfNPnHTAIBcZgMbO_NS5tAihXjCHzN3_QvHi7mpUFMBQFB8xrBKG10LpU6aJyAPRYrNqARLkZ5hOoIwt9gpy-vi9X348gQWbsdtR/s0/question3.2.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" width="763" border="0" data-original-height="1408" data-original-width="1526" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8zRW1_hH3qExlwjtSNYvQoPdsMeTiHuDYafafmRIgsfNPnHTAIBcZgMbO_NS5tAihXjCHzN3_QvHi7mpUFMBQFB8xrBKG10LpU6aJyAPRYrNqARLkZ5hOoIwt9gpy-vi9X348gQWbsdtR/s0/question3.2.png"/></a></div>
For the top 3 here it's almost a draw for the "Like it" category, with Payara taking a small 1% point lead. For the "Don't like" category it's WildFly however taking that same small 1% point lead with only 3% of its own users don't liking it, compared to 4% for Payara Server. When it comes to the neutral "Does the job" category GlassFish scores the highest, followed by WebLogic and closely followed by TomEE.
<p>
Let't take a look at the 2018 "Like it" results to compare:
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/4-like.svg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" width="763" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/4-like.svg"/></a>
</div>
Here we see WildFly has declined somewhat, going from 47% to 44%. As we've seen from the previous charts these percentage points didn't go into extra love. Payara Server on its turn gained a few percentage points, going from 39% to 44%. As we saw from the previous charts, some of these percentage points came from the "Love it" category. TomEE stayed at exactly the same percentage; 40% of its users liked it in 2018, and 40% still like it in 2020. WebLogic and WebSphere declined a little bit further among its users in our target audience, next to losing some points in the "Love it" category, they both lost about as much in the "Like it" category as well.
<p><br /></p>
<a name="apis"></a>
<h2>Question 4 - Which Java EE/Jakarta EE APIs have you used recently?</h2>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtY0k0dNK_npZM5-pLhYHesvUtUY2wyVownGkX9pd4F1BJb8wD3qY0IU_nKRDk7YhosH0GQ5uBr7Tn9GsYeeDQex4BVqzgZ9GJU727ww9x9GwmoLCxUim_gK9vRAisLAOK-XPJhT2kIQmb/s0/question4_2020.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" width="524" border="0" data-original-height="2200" data-original-width="1048" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtY0k0dNK_npZM5-pLhYHesvUtUY2wyVownGkX9pd4F1BJb8wD3qY0IU_nKRDk7YhosH0GQ5uBr7Tn9GsYeeDQex4BVqzgZ9GJU727ww9x9GwmoLCxUim_gK9vRAisLAOK-XPJhT2kIQmb/s0/question4_2020.png"/>
</a>
</div>
The outcome of which APIs are most often used is not that surprising, or maybe in a way it is. Jakarta Persistence (JPA) leads the pack. This is itself not surprising, but what may be surprising is that this is so despite the fact that Jakarta EE and its offspring doesn't really focus on Jakarta Persistence at all. Its most well known implementation, Hibernate, is very active, but the Jakarta Persistence spec/API project is not active at all.
<p>
Comparing this outcome with the 2018 result doesn't really show any major differences:
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/5.svg" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" width="623" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/5.svg"/></a>
</div>
When we divide this chart into 3 sections from top to bottom, and consider each section an unordered bag, there's virtually no change at all:
<p>
Popular
<pre>
{Persistence, CDI, REST, Faces, Enterprise Beans, Servlet, Transactions, Bean Validation}
</pre>
<p>
Neutral
<pre>
{Expression Language, JNDI, XML Binding, Mail, JSON Binding, XML Web Services, Messaging, Security, JSON Processing, WebSocket}</pre>
<p>
Not so popular
<pre>
{Pages/Tags, Concurrency, Batch, Connectors, Authentication, Authorization}
</pre>
We essentially only see Jakarta Transactions having switched from being in the second group in 2018, to being in the first group in 2020, swapping places with JNDI. Likewise Jakarta JSON Binding swapped groups with Pages/Tags.
<p>
It must be noted that Authentication and Authorization are SPIs, and as such not so much intended to be used directly by the average Jakarta developer. These are used however internally by Jakarta Security, and depending on the server or runtime by the Jakarta Servlet implementation as well. Because their standalone usage is so low, it's been proposed to fold them into Jakarta Security at some point.
<p><br /></p>
<a name="servlet-used"></a>
<h2>Question 5 - Have you used a (standalone) Servlet container recently?</h2>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggTE3PasJ3NDnSY59abFbZpfBQuqAb4VQGF066xaaehN3WHeyTOj0QnGG7MbUpj2PTxYz1p7Jm73jqtApYeSRlwdIOwBSEnZ3jbqrunJRUgzaO-fhLJ_1d83CjMif8AKRv2lUlGO9viaa5/s0/question5.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" width="523" border="0" data-original-height="434" data-original-width="1046" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggTE3PasJ3NDnSY59abFbZpfBQuqAb4VQGF066xaaehN3WHeyTOj0QnGG7MbUpj2PTxYz1p7Jm73jqtApYeSRlwdIOwBSEnZ3jbqrunJRUgzaO-fhLJ_1d83CjMif8AKRv2lUlGO9viaa5/s0/question5.png"/></a></div>
<p>
A standalone Servlet container is a server that supports at least the Servlet API, and typically a number of strongly related APIs such as the Servlet Container Profile of Jakarta Authentication, Jakarta Expression Language, JNDI, Jakarta Pages and Jakarta WebSocket.
<p>
As it appears, about half of the respondents have used such Servlet container, while the other half hasn't (and thus only used something like a full or web profile Jakarta EE server).
<p>
Comparing this outcome with 2018 shows yes and no have swapped places, but it's still quite close.
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/6.svg" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" width="523" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/6.svg"/></a>
</div>
<p><br /></p>
<a name="servlet-which"></a>
<h2>Which Servlet containers have you used recently?</h2>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOvN48lRLVSXP96ZUeZm5q1_aTrHp1Vvg5zxEnDW1s3vurfbjHkmhnWIIrx0uf9AAxjYagnflOV4xjpRb9nKoeAWHJU3g3EMqoPip9UKKdlUGlVMpBl1t_VhoF5DHGi4hGg7r_zl6q45w6/s0/question6_.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" border="0" width="498" data-original-height="632" data-original-width="996" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOvN48lRLVSXP96ZUeZm5q1_aTrHp1Vvg5zxEnDW1s3vurfbjHkmhnWIIrx0uf9AAxjYagnflOV4xjpRb9nKoeAWHJU3g3EMqoPip9UKKdlUGlVMpBl1t_VhoF5DHGi4hGg7r_zl6q45w6/s0/question6_.png"/>
</a>
</div>
Hardly surprising to those in the industry, Tomcat leads the pack with 80% of respondents who used a standalone Servlet container claiming to have used Tomcat.
<p>
Comparing this with 2018 we see both Jetty and Undertow have gained a few percentage points of popularity, while Tomcat has lost about as much:
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/7.svg" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" width="498" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/7.svg"/></a>
</div>
<p><br /></p>
<a name="ee-in-war"></a>
<h2>Question 7 - Which additional Java EE/Jakarta EE libraries do you use with your Servlet container?</h2>
<small>
<i>E.g by adding them to your .war. Note this question only concerns implementations of Java/Jakarta EE specs, not other libraries like Spring, PrimeFaces, OmniFaces, DeltaSpike, etc</i></small>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-URtl7h9mk6SjekCqKWaPK5PcUSMHS1EeWUmS7DYTAfV6lWI2xInd4vmuFYVa-SotG4UsfQlqTzX44yCiZlRUvBC7Ql1WQGGUuBpDA_iL9l7Z_-jUqP34MXuGma_znveoORll-LUQjp8v/s0/question6_2020.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" width="410" border="0" data-original-height="1424" data-original-width="820" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-URtl7h9mk6SjekCqKWaPK5PcUSMHS1EeWUmS7DYTAfV6lWI2xInd4vmuFYVa-SotG4UsfQlqTzX44yCiZlRUvBC7Ql1WQGGUuBpDA_iL9l7Z_-jUqP34MXuGma_znveoORll-LUQjp8v/s0/question6_2020.png"/>
</a>
</div>
Corresponding to most people saying that they use Jakarta Persistence (JPA), when it comes to Servlet users over 2/3 of them add Hibernate to their war archive, while an additional 22% adds EclipseLink, and 7% adds OpenJPA. We're also happy to see that the person who asked us to include DataNucleus in the choices has likely participated again, and was this time able to choose that option. Rounded up it represents another 1%.
<p>
Perfectly corresponding with the APIs that people use in general, CDI is at the second place of things people add. 46% of them add Weld, while 6% adds OpenWebBeans.
<p>
As for Jakarta REST (JAX-RS) it's interesting to see that Jersey and RESTEasy are added about as often.
Comparing with 2018 again, we see a few things:
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/8.svg" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" width="623" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/8.svg"/></a>
</div>
CDI (Weld) usage has clearly gone up, while Jersey is added a lot less and RestEasy a lot more. Combining those two makes that Jakarta REST (JAX-RS) is probably used about as often with a Servlet container as before.
<p>
Soteria, a Jakarta Security implementation has gone up quite a bit as well, relatively speaking. This is interesting. Soteria was particularly designed to be usable on multiple servers and runtimes, but until recently there were some practical issues with Soteria on Tomcat, and <a href="https://arjan-tijms.omnifaces.org/2020/12/jakarta-security-and-tomcat-10.html">this has only been truly fixed</a> after the survey started.
<p>
For the "Other" category, people mentioned Spring, PrimeFaces, OmniFaces and DeltaSpike, perhaps not unsurprisingly.
<p><br /></p>
<a name="ee-in-war-number"></a>
<h2>Question 8 - On average, how many Java EE/Jakarta EE libraries do you add when using a Servlet container?</h2>
<small><i>E.g by adding them to your .war. Note this question only concerns implementations of Java EE/Jakarta EE specs, not other libraries like Spring, PrimeFaces, OmniFaces, DeltaSpike, etc</i></small>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtcFnciw1bf0C2HGCRj5Aw3nsevmdsy9hUw0FUbzvqBWg1YeJIOREWEv8lk6l3Tr4b1VmHvAd8e8WFTUYeqvBQ-Cgo78-x5d5crswasXBVAPfBIHf9po__8Gx7GtqS2aSiEt92y0aq4vEK/s0/question8_2020.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" width="281" border="0" data-original-height="594" data-original-width="562" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtcFnciw1bf0C2HGCRj5Aw3nsevmdsy9hUw0FUbzvqBWg1YeJIOREWEv8lk6l3Tr4b1VmHvAd8e8WFTUYeqvBQ-Cgo78-x5d5crswasXBVAPfBIHf9po__8Gx7GtqS2aSiEt92y0aq4vEK/s0/question8_2020.png"/></a></div>
Not asked, but deduced from the total amount of people who said to use a Servlet container, and the amount of people answering this question, there were around 8% of people not adding any Jakarta EE libraries to their war archive.
<p>
We see here that 37% of users of a Servlet container in our target audience add more than 4 Jakarta EE libraries to their war archive. Adding exactly 3 was another popular choice, though interestingly enough adding exactly 4 was quite a bit less popular. Of course our target audience consists of users particularly interested in Jakarta EE, so the above absolutely does not men 37% of all Servlet container users add so many libraries.
<p><br /></p>
<a name="mp-apis-used"></a>
<h2>Question 9 - Have you used MicroProfile APIs recently?</h2>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXLz0QzXhKJMSPZ2RLbmNwElX6AiENucRY_l4PdcMjVV7F9kiDzXbdpy4Ds6JhxTajSWeLzMt_RHsoHSVyT7_GhLM9jHyiQMsqlcVls4gkvoKficpAVlRyQu72boPNSQytfFZvyFMtU10x/s0/question9_2020.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="2020" width="479" border="0" data-original-height="464" data-original-width="958" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXLz0QzXhKJMSPZ2RLbmNwElX6AiENucRY_l4PdcMjVV7F9kiDzXbdpy4Ds6JhxTajSWeLzMt_RHsoHSVyT7_GhLM9jHyiQMsqlcVls4gkvoKficpAVlRyQu72boPNSQytfFZvyFMtU10x/s0/question9_2020.png"/></a></div>
<p>
<a href="https://microprofile.io">MicroProfile</a> is an industry effort to bring extra APIs into the EE fold for things which Jakarta EE doesn't have an API now, such as configuration and metrics. At the same time MicroProfile is also a little like a profile such as WebProfile, where only those extra APIs are included as well as Jakarta REST, Jakarta JSON and CDI.
<p>
Lets right away compare the 2020 result to the 2018 one:
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/9.svg" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="2018" width="479" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/9.svg"/></a>
</div>
In 2018 MicroProfile was still relatively new, and hence only 16% had used any of its APIs. In 2020 the situation is quite different. MicroProfile is now much more established, and in percentage points its usage has doubled.
<p><br /></p>
<a name="mp-products"></a>
<h2>Question 10 - Which MicroProfile products have you used recently?</h2>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCMjhEGiaBtEjYVCKTWpPrFjJfx3N-_cXNEd0MHmM_MydM_fW9wPsU1wbcj41gmJm_2_G2rws8hx0k76TAT1Ur5FNJBST2fPw3tkvCUD9E5ZPJArxb-57XXLFy1pKZntjpzki4ifi0aHDX/s0/question10_2020.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="2020" width="358" border="0" data-original-height="1170" data-original-width="716" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCMjhEGiaBtEjYVCKTWpPrFjJfx3N-_cXNEd0MHmM_MydM_fW9wPsU1wbcj41gmJm_2_G2rws8hx0k76TAT1Ur5FNJBST2fPw3tkvCUD9E5ZPJArxb-57XXLFy1pKZntjpzki4ifi0aHDX/s0/question10_2020.png"/>
</a>
</div>
As can be seen the popularity of MicroProfile products largely mirrors the popularity of Jakarta EE products. Red Hat's offerings are squarely on top, followed by Payara with some distance, followed by IBM's Open Liberty and then Oracle's Helidon.
<p>
Interestingly, when it comes to MicroProfile, the Jakarta EE products of Red Hat and Payara are used approximately as often as their non-Jakarta EE products, with only a small edge for the non-Jakarta EE versions. It must me realised though that even though Quarkus and Payara Micro are not EE certified, they both contain many EE components.
<p>
Payara Micro is actually very close to Payara Server, with only a few EE components removed (like a Jakarta Messaging broker). Quarkus is more difficult to qualify in terms of EE. Via its <a href="https://code.quarkus.io">app generator</a> one can see it supports a bewildering amount of different components, and there's no explicit mention of EE. Eagle eyed readers however would be quick to recognise a multitude of components which are in fact originating from, based on, or used for Jakarta EE.
<p>
Something particular noteworthy is that this list doesn't really contain any "pure" MicroProfile implementation. With that we mean an implementation that only implements MicroProfile and nothing else. Somewhat ironically given the history, Helidon maybe comes closest to that, although it also integrates <a href="https://medium.com/helidon/helidon-and-jpa-da20492f5395">Jakarta Persistence and Jakarta Transactions</a>, as well as <a href="https://medium.com/helidon/websockets-in-helidon-mp-48259cf808f1">Jakarta WebSockets</a>.
<p>
We're particularly happy to see that <a href="https://piranha.cloud">Piranha Cloud</a> has a small amount of users already. Piranha Cloud is our own platform. At the moment of writing it's still in development and not fully production ready yet.
Comparing with the 2018 results shows many differences:
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/10.svg" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="2018" width="479" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/10.svg"/></a>
</div>
The biggest change is clearly that Red Hat has stopped development for WildFly Swarm, and has folded it into regular WildFly and its new Quarkus. WildFly Swarm initially had strongly integrated, non-reusable MP implementation components, but later in its life these had been refactored into the reusable component set called <a href="https://smallrye.io">SmallRye</a>. SmallRye is occasionally mistaken for a MicroProfile product/server itself, but it's not. It's a collection of implementations, e.g. for MP JWT, that can be used by any server or platform.
<p>
Payara Micro and Open Liberty both saw a rather big decline in usage. Hammock unfortunately stopped its development, although it still has a 1% user base left from its initial 3%.
<p><br /></p>
<a name="mp-apis-which"></a>
<h2>Question 11 - Which MicroProfile APIs have you used recently?</h2>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrxKoNw_jY9OYHlQRUwUstuWP9EEabGXZ9xAK_7-S5RJvTjXG2sIOOIFFU-gj1Ulj9uQFfc-4V77lSKjeMp2mvDAga-3xGu18G2ul4A7bwVft12XTzvCgc8D8U4zuPwNpZLEwPh-EQEqhl/s0/question11_2020.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="2020" width="510" border="0" data-original-height="768" data-original-width="1020" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrxKoNw_jY9OYHlQRUwUstuWP9EEabGXZ9xAK_7-S5RJvTjXG2sIOOIFFU-gj1Ulj9uQFfc-4V77lSKjeMp2mvDAga-3xGu18G2ul4A7bwVft12XTzvCgc8D8U4zuPwNpZLEwPh-EQEqhl/s0/question11_2020.png"/></a></div>
There's clearly 3 groups of popularity here. Config and Rest Client are in top group, Health, Metric, and Open API make up the second group, and the last group is JWT, Open Tracing and Fault Tolerance.
Comparing with the 2018 results shows some differences:
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/11.svg" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="2018" width="479" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/11.svg"/></a>
</div>
In 2018 Rest Client was still rather new and wasn't used much then (to be fair, it wasn't even implemented by all vendors at that point). Config, which was already at the top in 2018, has seen even more usage in 2020. Incidentally, Config was initially planned for Java EE 8 under the name of Java EE 8 Configuration. Via projects like <a href="https://deltaspike.apache.org">DeltaSpike</a> this type of configuration has been used in EE applications since around 2010. It's not surprisingly then that Config is proposed to be moved in some way to Jakarta EE, or that Jakarta EE in some way imports Config.
<p><br /></p>
<a name="ee-mp-groups"></a>
<h2>Question 12 - What's your preferred situation regarding MicroProfile vs Jakarta EE?</h2>
There have been some teething issues regarding the alignment between EE and MP, which are now both at the Eclipse foundation, and being worked on by mostly the same people. We therefor asked what users like to see regarding alignment:
<ol>
<li>MicroProfile joining up with Jakarta EE</li>
<li>MicroProfile and Jakarta EE being two separate frameworks</li>
</ol>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtVKQsuuN4fCY953dPVDiKj9_5O-37hQkpDfu0IADVTuCTpAZR_4vVX4Hc1zShtFDIIeSHzcYzmn9fvsfXfcZHtmSVqkdOmfEyuOmrOFA43YjdJSnV2xJMpz0Uz-bM6SnPbhwfR5oDZAUX/s0/question12_2020.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="2020" width="526" border="0" data-original-height="504" data-original-width="1052" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtVKQsuuN4fCY953dPVDiKj9_5O-37hQkpDfu0IADVTuCTpAZR_4vVX4Hc1zShtFDIIeSHzcYzmn9fvsfXfcZHtmSVqkdOmfEyuOmrOFA43YjdJSnV2xJMpz0Uz-bM6SnPbhwfR5oDZAUX/s0/question12_2020.png"/>
</a>
</div>
As can be seen, at 61% there's strong support for MicroProfile joining up with Jakarta EE, although the 31% who like to see them as separate frameworks is certainly not a small group either.
There were some interesting comments:
<p>
<i>"There should be a common base - config + injection that both should use. Whether it is Jakarta or MP or both is not that significant I think"</i>
<p>
<i>"Microprofile as Cutting Edge Jakarta EE standardizing after things are well established "</i>
<p>
<i>"Having more than one standard is going to cause more confusion "</i>
<p>
<i>"Using MP as incubator for Jakarta EE but use the jakarta namespace also for MP. So the users will not need to migrate once the MP Apis are moved to Jakarata EE "</i>
<p><br /></p>
<a name="ee-mp-products"></a>
<h2>Question 13 - What Jakarta EE and MicroProfile products do you prefer?</h2>
<small><i>
Separate products: A product implements only the EE APIs (like e.g. GlassFish or WebLogic), or only the MP APIs (like e.g. Helidon)<br/>
Single product: A product implements both the EE and MP APIs and fully allows them to be used together (like e.g. Payara or recent WildFly releases)</i></small>
Another question about the alignment, now from a product perspective, with the following options:
<ol>
<li>Separate products for the EE and MP APIs</li>
<li>Single product for both the EE and MP APIs</li>
<li>Don't care</li>
</ol>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEix0K1oL0EOohp2hTbbjVU74FzYlNqeNgXdmmn2wMX9NS16pkERieFfcd8FxUIPoSOPw_lbcsHEctmV6grsjVnv7FPJjk0lXYtH5a4AcL6E6MqfDrRZv-0zbE25OnGNHmKPgDk4IimX44G9/s0/question13_2020.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="2020" width="400" border="0" data-original-height="498" data-original-width="800" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEix0K1oL0EOohp2hTbbjVU74FzYlNqeNgXdmmn2wMX9NS16pkERieFfcd8FxUIPoSOPw_lbcsHEctmV6grsjVnv7FPJjk0lXYtH5a4AcL6E6MqfDrRZv-0zbE25OnGNHmKPgDk4IimX44G9/s0/question13_2020.png"/>
</a>
</div>
In broad lines the outcome here mirrors that of the previous question. The presence of a "Don't care" option did influence both the "together" and "separate" results, but "separate" more so than "together".
<p><br /></p>
<a name="ee-alt-known"></a>
<h2>Question 14 - Which of the following products that support one or more Jakarta EE APIs, but are not traditional or certified EE application servers, have you heard of?</h2>
<small><i>Note that this question only asks if you have heard of these. Whether you actually used them or not doesn't matter.</i></small>
<p>
Only 36% of the respondents answered this question, so we'll mention two percentages here: the first the percentage relative to the total number of respondents, the second number relative to those who answered the question.
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRkD4MOqAsToSm_GeMptig0KKr032HqpA7V24kss0oc9Shb15j8EncY9yFVSabTzaRCi6KLk4aRVi_gglQHgkE_GOvYqq8VZNhmIhUlqoZ57va_Cg05HNvXlmoaWZIdaqKsxQRmYIkA6Jt/s0/question14_2020.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="2020" width="466" border="0" data-original-height="636" data-original-width="932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRkD4MOqAsToSm_GeMptig0KKr032HqpA7V24kss0oc9Shb15j8EncY9yFVSabTzaRCi6KLk4aRVi_gglQHgkE_GOvYqq8VZNhmIhUlqoZ57va_Cg05HNvXlmoaWZIdaqKsxQRmYIkA6Jt/s0/question14_2020.png"/>
</a>
</div>
Not surprisingly, Helidon is most well known among respondents. 27% of all respondents claims to have heard of it. We're also happy to see that 16% has heard about Piranha Cloud already :)
<p><br /></p>
<a name="ee-cadence"></a>
<h2>Question 15 - What would be the ideal cadence (time between major releases) for Jakarta EE?</h2>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjO-I7sXYguxVuPK-vwHvhb7uRvli9V-4SGB_YE6nfvxPhaQeQ61hAOgMNT7FcelnMZISLw6zP2xfaZQIatEmDwGnQAtdyl49iwuOEyEs9iBjfKgjbFelStLrGktGX10bAYynGENCZZFBG/s0/question15_2020.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" width="373" border="0" data-original-height="604" data-original-width="746" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjO-I7sXYguxVuPK-vwHvhb7uRvli9V-4SGB_YE6nfvxPhaQeQ61hAOgMNT7FcelnMZISLw6zP2xfaZQIatEmDwGnQAtdyl49iwuOEyEs9iBjfKgjbFelStLrGktGX10bAYynGENCZZFBG/s0/question15_2020.png"/>
</a>
</div>
Now that Jakarta EE has moved to the Eclipse foundation, and the work for Jakarta EE 10 is about to begin (and in some cases has already begun), the question is what the release cadence should be. For Java EE under the JCP this <a href="https://arjan-tijms.omnifaces.org/2014/10/java-ee-process-cycles-and-server.html">greatly varied</a> but was on average about 3 years.
<p>
Here we see that there's strong support for a yearly cadence under our respondents. Taking twice as much time (and hence including more per release), or taking half of that time (and thus including less per release) are about as populair. The existing cadence of 3 years did not appear to be very popular at all.
<p>
Some of the comments:
<p>
<i>"LTS every 2 years, minor releases every year, bugfixes evey 6 months "</i>
<p>
<i>"Feature releases and LTS like Java SE does it for stability and innovation balance "</i>
<p>
<i>"Hard to say but 6 months would definitively be too short for us. We have many small applications with only a few releases each year (~ 1 to 4 releases). "</i>
<p><br /></p>
<a name="javax-jakarta"></a>
<h2>Question 16 - Knowing that Jakarta EE 9 contains only the javax to jakarta namespace change, do you:</h2>
<ol>
<li>Migrate to Jakarta EE 9 as soon as your favourite server (e.g. Wildly) comes out with an EE 9 version</li>
<li>Wait for Jakarta EE 10 with actual new features</li>
<li>Other</li>
</ol>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnOTLNZuNqmTfuk925OtIoRPyiVqbzkA6tXGh-0HSrPtBw6h8yLR7zdPp0hBIzZpX5rNrBg8XUrf0POAbGQuqejTNDLBe_qROpHE85qW-UGLdtI0uzrsXM7_s1NMbYIxR1pZ6a48TGqFPM/s0/question16_2020.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" width="420" border="0" data-original-height="494" data-original-width="840" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnOTLNZuNqmTfuk925OtIoRPyiVqbzkA6tXGh-0HSrPtBw6h8yLR7zdPp0hBIzZpX5rNrBg8XUrf0POAbGQuqejTNDLBe_qROpHE85qW-UGLdtI0uzrsXM7_s1NMbYIxR1pZ6a48TGqFPM/s0/question16_2020.png"/>
</a>
</div>
There's not a strong support for any specific option here. A slim majority of respondents claims to wait for Jakarta EE 10, but it's really a slim margin.
<p>
Some of the comments:
<p>
<i>"Wait to give my other dependencies time to catch up on EE9 "</i>
<p>
<i>"We will try to migrate to jakarta EE 9 once tomee implementation is based on jakarta, without bytecode transformation and other libraries are migrated as well (logback, javamelody,etc). We think it will be a very painful task "</i>
<p>
<i>"Migrate as soon as all the (many) internal dependencies update "</i>
<p>
<i>"Depends on when my cloud service provider offers it"</i>
<p>
<i>"Do new development on the leading edge; migrate others as we go. "</i>
<p><br /></p>
<a name="ee-apis-update"></a>
<h2>Question 17 - Which APIs would you most like to see updated in the next version of Jakarta EE? </h2>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOb2eZWvZxxExI0UI6L6Vv1YqVaPwrZR8lloUu3vbI2rzfG1gkjto-WzZrdj7PvJqJVT-OvW81UWDqa4A_xJb0OrXLZQ5wX3EE1pnc9B47dsO0NRkGLIJJopNOEbmCbI6i52h2n9VisuHx/s0/question17_2020.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="2020" width="548" border="0" data-original-height="1216" data-original-width="1096" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOb2eZWvZxxExI0UI6L6Vv1YqVaPwrZR8lloUu3vbI2rzfG1gkjto-WzZrdj7PvJqJVT-OvW81UWDqa4A_xJb0OrXLZQ5wX3EE1pnc9B47dsO0NRkGLIJJopNOEbmCbI6i52h2n9VisuHx/s0/question17_2020.png"/></a></div>
For this question respondents were asked to rank the Jakarta EE APIs. From this ranking a total score was calculated, based on a combination of how often something is at position 1 (max points) how often something is at position 2 (little less than max points) etc.
<p>
Looking at the total ranking we see the most desire for updates is in CDI, followed by Jakarta Persistence (JPA) and Jakarta Rest (JAX-RS). These three largely follow from what people actually use. Jakarta Security stands out here: respondents relatively speaking more often want to see it improved compared to how often they are using it. Jakarta Mail (JavaMail) is the opposite here. It's used more often compared to how often people like to see it improved.
<p>
This may be explained by Jakarta Security being a small and new API. Introduced in Java EE 8, it only covers the basics. Advanced features were initially left for Java EE 9, but then the entire transition to Eclipse started. Jakarta Mail likely simply does what it needs to do: send email. There's not that much demand for anything else there, it's a stable and fairly complete API.
<p>
Comparing with the 2018 results we don't see a lot of differences (note that for the 2020 question we folded several highly dependent APIs, such as all the Security APIs, into one):
<div class="separator" style="clear: both;">
<a href="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/13-tot.svg" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="2018" width="548" border="0" data-original-height="852" data-original-width="1246" src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/13-tot.svg"/></a>
</div>
The fact that we don't see a lot of differences may be some kind of validation for the numbers. Functionally nothing has changed since 2018, as only the migration to Eclipse / Jakarta has taken place. The wishes people had for Java EE (now Jakarta EE) in 2018 still hold for today.
<p><br /></p>
<a name="ee-improve-general"></a>
<h2>Question 18 - How important are the following general options to improve Jakarta EE?</h2>
For this question people could "buy" features for Jakarta EE using 100 points that they could spend at will.
<p>
The features were as follows:
<ul>
<li>Aligning specifications and features to take better advantage of CDI, making CDI truly the central component model for Jakarta EE </li>
<li>Aligning specifications and features to take better advantage of Java SE innovations</li>
<li>Including more commonly used features that are vendor-specific today or available outside Jakarta EE technologies</li>
<li>Officially add alternative deployment models such as the Uberjar, run .war from command line, etc.</li>
<li>Aggressively deprecate and remove legacy features</li>
<li>Aggressively remove everything that is already @Deprecated but still there </li>
</ul>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggaOUirQ8akMnwPFzu8EfwgUfrIZbUHAGVyPh3YmH2jzONXRbcNgnv2lwepxwW_YMPe2u7_jSwj4Ro06p0do16xqKFRSRIiDravOqN6lhwTWNiGtg0_cix_Yk3sAjunlA-mAz-u2LPa429/s0/question18_2020.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" width="738" border="0" data-original-height="728" data-original-width="1476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggaOUirQ8akMnwPFzu8EfwgUfrIZbUHAGVyPh3YmH2jzONXRbcNgnv2lwepxwW_YMPe2u7_jSwj4Ro06p0do16xqKFRSRIiDravOqN6lhwTWNiGtg0_cix_Yk3sAjunlA-mAz-u2LPa429/s0/question18_2020.png"/></a></div>
Under our respondents there's a very clear winner here. "CDI as the central component model". This is good news, as this is indeed the direction Jakarta EE is going in. For instance, Jakarta REST has a clear <a href="https://github.com/eclipse-ee4j/jaxrs-api/wiki/Roadmap">plan to rebase on CDI</a>, and there's <a href="https://github.com/eclipse-ee4j/concurrency-api/issues/43">several</a> <a href="https://github.com/eclipse-ee4j/concurrency-api/issues/98">plans</a> to move Enterprise Beans features to CDI versions in the Concurrency API.
<p>
Taking advantage of new Java SE innovations is high on the list as well. This could include for instance fairly old things that have still not been fully utilised such as lambdas, or things that are theoretically old, but practically still very new too many people, such as modules. Records, and in the future light-weight user mode threads (aka fibers) could have a massive impact on some APIs.
<p>
Alternative deployment models were less popular among our respondents, although that could just mean people don't see a point in standardising them and using them in a vendor specific way is enough.
<p>
Removing and/or deprecating things ranked lowest. Perhaps this is somewhat surprising, as at the same time people ask to reduce the cognitive load in Jakarta EE, for which removing legacy things should surely help.
<p><br /></p>
<a name="ee-improve-specific"></a>
<h2>Question 19 - How important are the following more specific options to improve Jakarta EE?</h2>
Like the previous question, people could buy features again using 100 points. This time they were:
<ul>
<li>Add more SQL features to JPQL and the Criteria API such as sub-selects</li>
<li>Make REST (JAX-RS) resources fully CDI beans, deprecate @Context</li>
<li>CDI friendly equivalents for @Asynchronous, @Schedule and @Lock</li>
<li>REST friendly, extensionless URLs for Faces (JSF)</li>
<li>@Service CDI stereotype that seeks to deprecate EJB @Stateless</li>
<li>Have Servlet and REST (JAX-RS) share a common HTTP engine</li>
<li>Make Servlets fully CDI beans (in Jakarta EE only, allows for scopes and interceptors)</li>
<li>CDI friendly, modernized equivalents for @RolesAllowed and @RunAs</li>
<li>CDI friendly equivalent for @MessageDriven</li>
<li>@ManagedExecutorServiceDefinition annotation for more portably defining managed executors</li>
</ul>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwiX3oa-QzIkj6-_bgN5vLgafODaJ0Tio2N_0JxkqhCSvV5q2rRFVr15lcIiDhYfmMUN8xksbh5q51e6YBua5mXD6CNf_gtiuQK8PLFZtSviswcm9OvRL5NmGSTjr_xLuKV4bMu3SltIJ1/s0/question19_2020.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="2020" width="762" border="0" data-original-height="754" data-original-width="1524" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwiX3oa-QzIkj6-_bgN5vLgafODaJ0Tio2N_0JxkqhCSvV5q2rRFVr15lcIiDhYfmMUN8xksbh5q51e6YBua5mXD6CNf_gtiuQK8PLFZtSviswcm9OvRL5NmGSTjr_xLuKV4bMu3SltIJ1/s0/question19_2020.png"/>
</a>
</div>
For this list of more specific features there's one big winner, and that's adding more SQL features to Jakarta Persistence. This corresponds pretty well with people liking to see improvements in Jakarta Persistence.
<p>
At the second place we see REST resources becoming fully CDI, and the CDI equivalents for @Asynchronous, @Schedule and @Lock, which corresponds well to the improvements for REST and the CDI alignment that people like to see at a more general level. REST URLs for Faces scores quite high as well. For this JSF 2.3 did important <a href="https://arjan-tijms.omnifaces.org/p/jsf-23.html#1260">foundational work</a>, but it's still a bit of a <a href="https://arjan-tijms.omnifaces.org/2017/08/extensionless-urls-with-jsf-23.html">hassle to actually use</a> it. For Faces 4.0 we are targeting a simple option to activate this, as well as a new <a href="https://github.com/omnifaces/oyena/blob/master/action/README.md">action lifecycle</a>.
<p><br /></p>
<a name="comments"></a>
<h2>Question 20 - Do you have any final comments on how Jakarta EE can be improved in the future?</h2>
As an open question, people could leave a comment on what they thought about improving Jakarta EE.
A selection of those comments:
<p>
<i>"Jpa criteria is terrible to use. It would be good have an alternative "lite" criteria in jpa similar to hibernate one."</i>
<p>
<i>"JPA really is complex to use with the cloning; as long as you are in a request-response setting it is ok, but with a more long lived fat client it's complex. May introduce a mode where no clones are used."</i>
<p>
<i>"JNoSQL should align with the forthcoming ISO GQL rather than tying to TinkerPop."</i>
<p>
<i>"Standarize the jpa data repository abstraction (à la spring boot / micronaut data / quarkus panache). Merge MP config , fault tolerant, health check, rest client to Jakarta EE with the jakarta namespace. Make Jakarta Messaging support Kafka and standard messaging protocols... DEprecate ejb and move its APis to other corresponding specs Ahead of time CDI processing. Modularize the platforme (use some sort of starter instead of profiles) ... And we're good :)"</i>
<p>
<i>"I would like to see Jakarta EE 9 ASAP. At the moment I feel that there is an chaos and stagnation and more and more people are afraid to choose Java/Jakarta EE because they don't see the clear future."</i>
<p>
<i>"Release EE 10 ASAP, Spring is becoming de-facto standard "</i>
<p>
<i>"Remove EJB and include more security features of OAuth2, and other protocols. Also, make CDI very central to JakartaEE, and include latest Java SE features in future APIs of Jakarta EE. Also, let Jakarta EE support Java programming language exclusively, as primary and first class support. Other JVM languages should be given less preference over Java."</i>
<p>
<i>"There are 4 different annotations that 'inject' something: @Inject - inject a bean @Resource - inject a (typically) DataSource @EJB - inject an EJB @PersistenceContext - inject an EntityManager Wish it could all be just '@Inject' Also make sure works for constructor-injection as well as field-injection"</i>
<p>
<i>"Add Quarkus like build time optimizations, for example for CDI, Make the extensions API work in these environments, so these CDI implementations don't need a proprietary extension API"</i>
<p>
<i>"JEE was affected by seasonal fads, problems with updating and bureaucracy of big companies, I believe in the robustness, in the reliability for the craziest that the boys call me for continuing to start new projects my clients and I are very satisfied. Thank you for helping the community that is very strong and knows the power that the whole package has. As long as the JEE exists and I will use it."</i>
<p>
<i>"Make @DataSourceDefinition work with injected values vendor-neutral. Configuration in general across environments in a secure way."</i>
<p>
<i>"Get rid of legacy and complexity (focus on CDI) and get ready for cloud (MicroProfile)"</i>
<p>
<i>"I feel like MicroProfile born out of slow moving Java EE. Now both taking own route even though CN4J formed. May be once Jakarta 10 or 11 released. Make both Jakarta EE and MicroProfile under one brand. We already break namespace charge for Jakarta EE 9, not sure how many will upgrade for that immediately. Jakarta 10 might be good Candidate to remove some old or deprecated stuff, and then make Jakarta 11 naturally home for microphone. That's we taking of 2 years from now once Jakarta falls yearly release Cadence."</i>
<p>
<i>"Make every API based on CDI for consistency."</i>
<p>
<i>"Better specification related to microprofile and its interaction with Jakarta EE or its existing APIs like CDI or JAX-RS"</i>
<p>
<i>"make JEE and microprofile converge, I want to build a thin war and deploy it and needed resources from a simple command line that could be transformed into a systemd service or Podman container; hot reload on development mode."</i>
<br/>
<p>
A special mention for this comment, where the writer took quite a bit of effort: (we do wonder if this writer is familiar with Jakarta Security, or whether the security comment is refering to JASPIC/JACC and/or container specific/proprietary security):
<p>
<i>"
* first-class support for fully programmatic configuration and bootstrapping of all specs outside a JEE container. We should not need to use Arquillian, test modules from the spec vendors, or similar to write JUnit tests or to leverage our know-how with CDI, JPA, etc to write a non-server application. <br/>
* kill everything EJB with fire, nobody wants pooled beans with synchronization, wrapping of exceptions <br/>
* CDI annotations for calling a method periodically and on application startup. <br/>
* everything should be a CDI bean. <br/>
* OpenAPI support (contract-first development support by generating model, API interface from YAML, fully cover the spec when (de)serializing). <br/>
* JPA is a foot-cannon. Persistence as a side effect of in-memory object state is complex and thus unexpected behavior /mistake-prone and not worth the convenience. Also, mapping annotations are poorly thought out and can be contradictory (eg. a @XtoY can have both cascade and mappedBy set) or open to interpretation (eg should a @PrePersist work on an @Embeddable?). Vendors (at least Hibernate) don't fail on startup when annotations have contradictory settings but will have undefined behavior. Either create an alternative type-safe SQL building and ResultSet-to-Object mapper spec or refer users to Jooq, QueryDSL or similar. <br/>
* All the security stuff is awful, its much easier to write your own filter+interceptor for login and permission checking. Remove it <br/>
* Maybe support for working with AMQP, Kafka brokers (don't run them in the application server like JMS) <br/>
* It's probably all for nothing as Spring Boot has won and very few people will start a greenfield project in JEE."</i>
<p>
P.s. we had a few users mention the many open PRs in the Mojarra project. Yes, we're aware, and hope to be able to look at them soon. Any help in doing reviews and/or tests is highly welcomed!
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-7071181951100713552021-01-25T10:56:00.000-08:002021-01-25T10:56:21.668-08:00Jakarta EE 2020 Survey: which EE versions do people use?At OmniFaces we have a <a href="https://www.surveymonkey.com/r/jakarta2021a" target="_blank">survey running about Jakarta EE</a>.
<p>
The first question is about which version of Java EE/Jakarta EE people use. While the final results are not yet in, let's take a sneak peek at the preliminary results.
<h2>
Which versions of Java EE/Jakarta EE have you recently used? (select all that apply)
</h2>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpcttEDfvm2nAZkxSWD6THc-XhvNfnLFhC4P9k_Jq3Vs52QBoqfu0lZtNSsiXgTxhEr4yiVmyr7XuX0nSUPFJIF4lhwcoSiGyOf9IhKAiwQRosbNhzc-nDFL4wjhD1i84gzrFzI609H6U4/s0/Screenshot+2021-01-25+at+16.55.30.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" border="0" width="418" data-original-height="836" data-original-width="1192"
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpcttEDfvm2nAZkxSWD6THc-XhvNfnLFhC4P9k_Jq3Vs52QBoqfu0lZtNSsiXgTxhEr4yiVmyr7XuX0nSUPFJIF4lhwcoSiGyOf9IhKAiwQRosbNhzc-nDFL4wjhD1i84gzrFzI609H6U4/s0/Screenshot+2021-01-25+at+16.55.30.png"/>
</a>
</div>
Java EE 8 is clearly taking the lead with Jakarta EE 8 in the second place. We see that J2EE 1.4 and Java EE 5 usage is very low, though there's still a sizeable amount of people using Java EE 6 (about 10%). When we zoom a little into the Java EE 6 figure, we learn that Java EE 6 users do for a large part use higher versions as well:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcMd8_H4zlWod4Mcyq3g9bvkWM8OoVSgpo-FBmTZwGes9uvCSsJJUhKIpTQ2iupw9JpLl8P55XLpa2bev6WcJYod5jM6hBxAdrNSi27HoU5fqj1WYyNYDtwGOzJ2bTfLpfHCd7cCr6di_r/s0/Screenshot+2021-01-25+at+17.16.16.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" border="0" width="418" data-original-height="836" data-original-width="1270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcMd8_H4zlWod4Mcyq3g9bvkWM8OoVSgpo-FBmTZwGes9uvCSsJJUhKIpTQ2iupw9JpLl8P55XLpa2bev6WcJYod5jM6hBxAdrNSi27HoU5fqj1WYyNYDtwGOzJ2bTfLpfHCd7cCr6di_r/s0/Screenshot+2021-01-25+at+17.16.16.png"/></a></div>
As Java EE 8 and Jakarta EE 8 are functionally identical, and differ mainly by their license, it's perhaps interesting to look at how these two relate to each other. For that we looked at the results where people said to only use Java EE 8, only use Jakarta EE 8, or said to use both of them:
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVOxDhlmU6VD_I-hQKSgUd2CSXw7DJ8Jt9UFGeZbAV7YkK-Pua5a1vwP1xO2SFUvMBPEACxjOt2iIM6dJWOMUpD5Ie8W7oAcMuVb0uhWnhVdXU-w5bQ8CUmQHicygjprq3j44xf379tuum/s0/Untitled+Document.png" style="display: block; padding: 1em 0; text-align: center; ">
<img alt="" border="0" width="429" data-original-height="638" data-original-width="858" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVOxDhlmU6VD_I-hQKSgUd2CSXw7DJ8Jt9UFGeZbAV7YkK-Pua5a1vwP1xO2SFUvMBPEACxjOt2iIM6dJWOMUpD5Ie8W7oAcMuVb0uhWnhVdXU-w5bQ8CUmQHicygjprq3j44xf379tuum/s0/Untitled+Document.png"/></a></div>
As can be seen about half of the "8" users said to be using Java EE, with roughly 1 quarter using the Jakarta EE version and also roughly one quarter using both. It will be particularly interesting to see how these numbers will change in the future.
<p>
The Jakarta EE Survey 2020/2021 is still open. So if you haven't completed the survey yet, there's still time:
<div style="clear: both; border: 1px solid; text-align: center; padding: 1em 0;">
<b><a href="https://www.surveymonkey.com/r/jakarta2021">Enter the Jakarta EE Survey 2021</a></b>
</div>Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-37902957355485319612020-12-30T12:34:00.001-08:002020-12-30T13:28:47.214-08:00Jakarta Security and Tomcat 10Jakarta Security was introduceed as Java EE Security in Java EE 8. It facilitates portable application security that fully integrates with container security. This means that an application can provide an authentication mechanism, say for OATH2 or <a href="https://auth0.com/docs/quickstart/webapp/java-ee" target="_blank">Auth0</a> and that mechanism is treated just like build-in container mechanisms like FORM. All existing security code, such as the container determining access to a URL based on web.xml constraints, and things like @RolesAllowed and <a href="https://jakarta.ee/specifications/servlet/5.0/apidocs/jakarta/servlet/http/httpservletrequest#isUserInRole%28java.lang.String%29" target="_blank">HttpServletRequest.isUserInRole</a> automatically work as expected.
<p>
One of the compatible implementations of Jakarta Security is <a href="http://github.com/eclipse-ee4j/soteria">Soteria</a>. Soteria has been designed as a standalone library, that can be integrated with multiple servers. It depends on CDI, and the lower level SPIs <a href="http://jakarta.ee/specifications/authentication/2.0/jakarta-authentication-spec-2.0" target="_blank">Jakarta Authentication</a> and <a href="https://jakarta.ee/specifications/authorization/2.0/authorization-spec-2.0" target="_blank">Jakarta Authorization</a>.
<p>
Soteria <a href="https://blog.payara.fish/using-jakarta-security-on-tomcat" target="_blank">worked on Tomcat before</a>, but there were some issues. For one, when adding a CDI implementation like Weld to Tomcat, the BeanManager ends up in the JNDI location <i>java:comp/env/BeanManager</i>, while the specification defined location should be <i>java:comp/BeanManager</i>. The latest version of Soteria now looks at this location too, so no patching is required anymore.
<p>
Another issue was that Tomcat implements the servlet container profile of Jakarta Authentication, but not Jakarta Authorization. There are essentially two options to overcome that here:
<ol>
<li> Add Jakarta Authorization support to Tomcat </li>
<li> Implement an SPI for Soteria to use native Tomcat Authorization code </li>
</ol>
An independent implementation of Jakarta Authorization is available from the <a href="https://github.com/omnifaces/exousia" target="_blank">Exousia project</a>. This project recently added integration support specifically for Tomcat, so that we only need to add it as a dependency. To use Jakarta Security in Tomcat, we can create a Maven project with the following dependencies:
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&family=Waiting+for+the+Sunrise&display=swap');
</style>
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'><span style='color:#7f0055; '><</span><span style='color:#7f0055; '>dependency</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>groupId</span><span style='color:#7f0055; '>></span>jakarta.platform<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>groupId</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>artifactId</span><span style='color:#7f0055; '>></span>jakarta.jakartaee-api<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>artifactId</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>version</span><span style='color:#7f0055; '>></span>9.0.0<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>version</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>scope</span><span style='color:#7f0055; '>></span>provided<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>scope</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>dependency</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>dependency</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>groupId</span><span style='color:#7f0055; '>></span>org.glassfish.soteria<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>groupId</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>artifactId</span><span style='color:#7f0055; '>></span>jakarta.security.enterprise<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>artifactId</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>version</span><span style='color:#7f0055; '>></span>2.0.1<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>version</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>dependency</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>dependency</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>groupId</span><span style='color:#7f0055; '>></span>org.omnifaces<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>groupId</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>artifactId</span><span style='color:#7f0055; '>></span>exousia<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>artifactId</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>version</span><span style='color:#7f0055; '>></span>1.0<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>version</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>dependency</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>dependency</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>groupId</span><span style='color:#7f0055; '>></span>org.jboss.weld.servlet<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>groupId</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>artifactId</span><span style='color:#7f0055; '>></span>weld-servlet-shaded<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>artifactId</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>version</span><span style='color:#7f0055; '>></span>4.0.0.Final<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>version</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>dependency</span><span style='color:#7f0055; '>></span>
</pre>
Additionally, since Tomcat has a read-only JNDI, a file in <i>[war root]/META-INF/context.xml</i> is needed with the following content to make the <i>BeanManager</i> available:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'><span style='color:#7f0055; '><?</span><span style='color:#7f0055; font-weight:bold; '>xml</span><span style='color:#7f0055; '> </span><span style='color:#7f0055; '>version</span><span style='color:#7f0055; '>=</span><span style='color:#2a00ff; '>'</span><span style='color:#7f0055; font-weight:bold; '>1.0</span><span style='color:#2a00ff; '>'</span><span style='color:#7f0055; '> </span><span style='color:#7f0055; '>encoding</span><span style='color:#7f0055; '>=</span><span style='color:#2a00ff; '>'</span><span style='color:#2a00ff; '>utf-8</span><span style='color:#2a00ff; '>'</span><span style='color:#7f0055; '>?></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>Context</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>Resource</span>
name=<span style='color:#2a00ff; '>"</span><span style='color:#2a00ff; '>BeanManager</span><span style='color:#2a00ff; '>"</span>
auth=<span style='color:#2a00ff; '>"</span><span style='color:#2a00ff; '>Container</span><span style='color:#2a00ff; '>"</span>
type=<span style='color:#2a00ff; '>"</span><span style='color:#2a00ff; '>javax.enterprise.inject.spi.BeanManager</span><span style='color:#2a00ff; '>"</span>
factory=<span style='color:#2a00ff; '>"</span><span style='color:#2a00ff; '>org.jboss.weld.resources.ManagerObjectFactory</span><span style='color:#2a00ff; '>"</span>
<span style='color:#7f0055; '>/></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>Context</span><span style='color:#7f0055; '>></span>
</pre>
To test if everything works, put an empty beans.xml file in WEB-INF and a web.xml file with the following content:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'><span style='color:#7f0055; '><</span><span style='color:#7f0055; '>web-app</span>
xmlns=<span style='color:#2a00ff; '>"</span><span style='color:#2a00ff; '>http</span><span style='color:#2a00ff; '>:</span><span style='color:#7f0055; font-weight:bold; '>//</span><span style='color:#3f3fbf; '>xmlns.jcp.org</span><span style='color:#3f3fbf; '>/xml/ns/javaee</span><span style='color:#2a00ff; '>"</span>
xmlns:xsi=<span style='color:#2a00ff; '>"</span><span style='color:#2a00ff; '>http</span><span style='color:#2a00ff; '>:</span><span style='color:#7f0055; font-weight:bold; '>//</span><span style='color:#3f3fbf; '>www.w3.org</span><span style='color:#3f3fbf; '>/2001/XMLSchema-instance</span><span style='color:#2a00ff; '>"</span>
xsi:schemaLocation=<span style='color:#2a00ff; '>"</span><span style='color:#2a00ff; '>https</span><span style='color:#2a00ff; '>:</span><span style='color:#7f0055; font-weight:bold; '>//</span><span style='color:#3f3fbf; '>jakarta.ee</span><span style='color:#3f3fbf; '>/xml/ns/jakartaee</span><span style='color:#2a00ff; '> </span><span style='color:#2a00ff; '>https</span><span style='color:#2a00ff; '>:</span><span style='color:#7f0055; font-weight:bold; '>//</span><span style='color:#3f3fbf; '>jakarta.ee</span><span style='color:#3f3fbf; '>/xml/ns/jakartaee/web-app_5_0.xsd</span><span style='color:#2a00ff; '>"</span>
version=<span style='color:#2a00ff; '>"</span><span style='color:#2a00ff; '>5.0</span><span style='color:#2a00ff; '>"</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>security-constraint</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>web-resource-collection</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>url-pattern</span><span style='color:#7f0055; '>></span>/foo/*<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>url-pattern</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>http-method</span><span style='color:#7f0055; '>></span>GET<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>http-method</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>web-resource-collection</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>auth-constraint</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>role-name</span><span style='color:#7f0055; '>></span>g1<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>role-name</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>auth-constraint</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>security-constraint</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>security-constraint</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>web-resource-collection</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>url-pattern</span><span style='color:#7f0055; '>></span>/foox/*<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>url-pattern</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>http-method</span><span style='color:#7f0055; '>></span>GET<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>http-method</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>web-resource-collection</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>auth-constraint</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '><</span><span style='color:#7f0055; '>role-name</span><span style='color:#7f0055; '>></span>g2<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>role-name</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>auth-constraint</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>security-constraint</span><span style='color:#7f0055; '>></span>
<span style='color:#7f0055; '></</span><span style='color:#7f0055; '>web-app</span><span style='color:#7f0055; '>></span>
</pre>
Then add two classes:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;font-family: 'JetBrains Mono', monospace;'><span style='color:#7f9fbf; font-weight:bold; '>@BasicAuthenticationMechanismDefinition(realmName = "realm")</span>
<span style='color:#7f9fbf; font-weight:bold; '>@ServletSecurity(value = @HttpConstraint(rolesAllowed = "g1"))</span>
<span style='color:#7f9fbf; font-weight:bold; '>@WebServlet(urlPatterns = "/SecureServlet")</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>class</span> SecureServlet <span style='color:#7f0055; font-weight:bold; '>extends</span> HttpServlet {
<span style='color:#7f0055; font-weight:bold; '>private</span> <span style='color:#7f0055; font-weight:bold; '>static</span> <span style='color:#7f0055; font-weight:bold; '>final</span> <span style='color:#7f0055; font-weight:bold; '>long</span> serialVersionUID = 1L;
<span style='color:#7f9fbf; font-weight:bold; '>@Inject</span>
SecurityContext securityContext;
<span style='color:#7f9fbf; font-weight:bold; '>@Override</span>
<span style='color:#7f0055; font-weight:bold; '>protected</span> <span style='color:#7f0055; font-weight:bold; '>void</span> doGet(HttpServletRequest request, HttpServletResponse response)
<span style='color:#7f0055; font-weight:bold; '>throws</span> ServletException, <span style='color:#7f0055; font-weight:bold; '>IOException</span> {
response.getWriter().println(
<span style='color:#2a00ff; '>"Has access to /foo/bar "</span> +
securityContext.hasAccessToWebResource(<span style='color:#2a00ff; '>"/foo/bar"</span>, <span style='color:#2a00ff; '>"GET"</span>));
response.getWriter().println(
<span style='color:#2a00ff; '>"Has access to /foox/bar "</span> +
securityContext.hasAccessToWebResource(<span style='color:#2a00ff; '>"/foox/bar"</span>, <span style='color:#2a00ff; '>"GET"</span>));
}
}
<span style='color:#7f9fbf; font-weight:bold; '>@ApplicationScoped</span>
<span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>class</span> MyIdentityStore <span style='color:#7f0055; font-weight:bold; '>implements</span> IdentityStore {
<span style='color:#7f0055; font-weight:bold; '>public</span> CredentialValidationResult validate(UsernamePasswordCredential usernamePasswordCredential) {
<span style='color:#7f0055; font-weight:bold; '>if</span> (usernamePasswordCredential.compareTo(<span style='color:#2a00ff; '>"u1"</span>, <span style='color:#2a00ff; '>"p1"</span>)) {
<span style='color:#7f0055; font-weight:bold; '>return</span> <span style='color:#7f0055; font-weight:bold; '>new</span> CredentialValidationResult(<span style='color:#2a00ff; '>"u1"</span>, <span style='color:#7f0055; font-weight:bold; '>new</span> <span style='color:#7f0055; font-weight:bold; '>HashSet</span><>(asList(<span style='color:#2a00ff; '>"g1"</span>)));
}
<span style='color:#7f0055; font-weight:bold; '>return</span> INVALID_RESULT;
}
}
</pre>
<p>
Naming the app "security-test", deploying this to a default installed Tomcat 10 and requesting "http://localhost:8080/security-test/SecureServlet" via a web browser will show the basic authentication dialog from that browser. If we then authenticate with username "u1" and password "p1", we'll get to see the following result:
<pre style='margin-left:10px;color:#000000;background:#ffffff;font-size: 80%;line-height: 100%;'>Has access to /foo/bar true
Has access to /foox/bar false
</pre>
<p>
So what happened here?
<p>
Behind the scenes quite a lot. Soteria installed a <a href="https://jakarta.ee/specifications/authentication/2.0/apidocs/jakarta/security/auth/message/module/serverauthmodule" target="_blank">ServerAuthModule</a> with Tomcat, which uses Weld to find and call the CDI bean installed by <a href="https://jakarta.ee/specifications/security/2.0/apidocs/jakarta/security/enterprise/authentication/mechanism/http/basicauthenticationmechanismdefinition" target="_blank">@BasicAuthenticationMechanismDefinition</a>. This bean calls the <a href="https://jakarta.ee/specifications/security/2.0/apidocs/jakarta/security/enterprise/identitystore/identitystore" target="_blank">IdentityStore</a> <i>MyIdentityStore</i>, which is the one we defined in our small application and that validates the credentials we submit.
<p>
Furthermore, <a href="https://github.com/omnifaces/exousia/blob/master/src/main/java/org/omnifaces/exousia/spi/integration/tomcat/TomcatAuthorizationFilter.java#L67" target="_blank">Exousia copied the security constraints that Tomcat collected</a> to a Jakarta Authorization module, which is a store of permissions (aka Permission Store) that among others can be queried by Jakarta Authorization. The default implementation in Soteria of <a href="https://jakarta.ee/specifications/security/2.0/apidocs/jakarta/security/enterprise/securitycontext#hasAccessToWebResource%28java.lang.String,java.lang.String...%29" target="_blank">SecurityContext#hasAccessToWebResource</a> indeed results in such a query. In our web.xml file we defined two constraints on URL patterns; <i>/foo/*</i> needing role <i>g1</i> and <i>/foox/*</i> needing role <i>g2</i>. At the point of making that call, we're in role <i>g1</i>, so asking if we can access <i>/foo/bar</i> results in a <i>true</i>, while asking for access to <i>/foox/bar</i> results in a false. This shows that Jakarta Authentication (Exousia) works correctly on Tomcat and works correctly with Soteria.
<p>
There's a small caveat here. Exousia now copies the security constraints from Tomcat, but Tomcat keeps using its own internal repository for authorization decissions. The assumption here is that both Tomcat and Exousia perform the exact same algorithm, but there can of course be small subtle differences. A next step would be to integrate Exousia further in Tomcat by wrapping the <a href="https://github.com/apache/tomcat/blob/master/java/org/apache/catalina/Realm.java" target="_blank">Realm</a> and delegating methods like <a href="https://github.com/apache/tomcat/blob/master/java/org/apache/catalina/realm/RealmBase.java#L979" target="_blank">hasUserDataPermission</a>, <a href="https://github.com/apache/tomcat/blob/master/java/org/apache/catalina/realm/RealmBase.java#L806" target="_blank">hasResourcePermission</a>, and <a href="https://github.com/apache/tomcat/blob/master/java/org/apache/catalina/realm/RealmBase.java#L915" target="_blank">hasRole</a>.
<p style="font-family: 'Waiting for the Sunrise', cursive; font-size: 150%">
<i>Arjan Tijms</i>
</p>
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com6tag:blogger.com,1999:blog-4498889353428710313.post-90338780437157913802020-09-28T09:57:00.002-07:002021-01-25T11:02:44.966-08:00Jakarta EE Survey 2020/2021At OmniFaces we poll the community from <a href="http://arjan-tijms.omnifaces.org/2015/03/the-most-popular-java-ee-servers-in.html">time</a> to <a href="https://arjan-tijms.omnifaces.org/2018/03/java-ee-survey-2018.html">time</a> about Java EE (now Jakarta EE) and related technologies.
<p>
With the <a href="https://blogs.oracle.com/javamagazine/transition-from-java-ee-to-jakarta-ee" target="_blank">transfer of Java EE to Jakarta EE</a> now almost completed, people are now <a href="https://docs.google.com/document/d/1uZFBoIujXCc-gQhCzh_ZdlKEsrsV0yVVIHzBTI3usF8/edit" target="_blank">starting to think about Jakarta EE 10</a>, the first Jakarta EE release after Java EE 8 having new featues. As such it's a good time to poll the community again.
<p>
In the 2020/2021 edition, there are 4 categories of questions again:
<ul>
<li>Current usage of Java EE / Jakarta EE</li>
<li>Servlet containers</li>
<li>APIs related to Java EE / Jakarta EE</li>
<li>The future of Jakarta EE</li>
</ul>
<p>
Compared to 2018, we simplified some of the questions somewhat, omitting some of the less popular options to make it more manageable. We added questions about the future of Jakarta EE and MP together, the preferred Jakarta EE cadence, and generally updated the choices (such as adding <a href="https://quarkus.io" target="_blank">Quarkus</a>, which wasn't quite on the radar in 2018 and our own <a href="https://piranha.cloud" target="_blank">Piranha Cloud</a>).
<p>
Jakarta EE provides the opportunity to revitalise and modernise Java EE, but in order to do that it's more important than ever that we know what matters to all of its users out there.
<p>
So therefor we'd like to invite all Java EE and Jakarta EE users to participate in
<b><a href="https://surveymonkey.com/r/jakarta2020">The Jakarta EE Survey 2020/2021</a></b>
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-42362356389240163152020-09-04T13:02:00.002-07:002022-12-14T10:17:04.124-08:00Hiring the right peopleA company's resources are typically not unlimited. Deciding for what next role to hire can be a challenging process. Does a company need extra engineers, or does it need more people on marketing? With a limited budget, choices will have to be made.
<p>
A good and competent boss will often consult with the staff to discover where the need is most pressing. <i> <br/>(click on the image for a larger version)</i>
</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVkZpGov37itKMX7O8srVhWQ0_7TFdivSEBZhLYF4gikScQUTQG31m9xUWW82QrJpsiLWD0GpaEibiMqsbJXQhJx_D7tATJaJ2H9awpM1P6_QsdCqHlDT4Il8uIPCBmVWUbfGGZsNv3egl/s2048/omnidevs_comic4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;">
<img border="0" data-original-height="1132" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVkZpGov37itKMX7O8srVhWQ0_7TFdivSEBZhLYF4gikScQUTQG31m9xUWW82QrJpsiLWD0GpaEibiMqsbJXQhJx_D7tATJaJ2H9awpM1P6_QsdCqHlDT4Il8uIPCBmVWUbfGGZsNv3egl/s1600/omnidevs_comic4.jpg" width="800" />
</a>
</div>
<p>
<a href="https://i.imgur.com/8R1D0mY.jpg">Even larger version</a>
</p>
<p>
Stay tuned for the next instalment!</p>
<p>
Previous strip: <a href="https://arjan-tijms.omnifaces.org/2020/08/perfecting-business-structure.html">Perfecting the business structure
</a>
Next Strip: <a href="https://arjan-tijms.omnifaces.org/2022/12/just-say-no.html">Just say no
</a>Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com1tag:blogger.com,1999:blog-4498889353428710313.post-89756367231213971262020-08-16T16:32:00.005-07:002020-09-04T13:04:05.690-07:00Perfecting the business structureIn programming we learn that we should not overcomplicate the architecture of our code. Yes, larger code bases may need a little bit more structure and benefit from certain architectural constructs that would be totally out of place in smaller code bases.
<p>
Sometimes though it's hard to resist using these constructs in code, since we imagine our tiny app being larger than it actually is, or because we think it soon will be. Interestingly, when structuring companies very similar pitfalls seem to exist.
</p><p>
Poor OmniDev head of engineering Liz and her friend Jennefer, who's head of marketing, are about to find out: <i> (click on the image for a larger version)</i>
</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIZlUlJIvG8fgMdDvuSX_U4CghkFwKsTfWc5mqQNI6R_cnaV5rN386FJjXq-ml_60U09qH7l4VbKiIJkUcI_xyuj09vqzpkf6X5PHKDYqjzPeVVS56HnWt-AW2Lod6tjoNf7AhGdVNUa7Z/s2048/omnidevs_comic3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;">
<img border="0" data-original-height="1132" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIZlUlJIvG8fgMdDvuSX_U4CghkFwKsTfWc5mqQNI6R_cnaV5rN386FJjXq-ml_60U09qH7l4VbKiIJkUcI_xyuj09vqzpkf6X5PHKDYqjzPeVVS56HnWt-AW2Lod6tjoNf7AhGdVNUa7Z/s1600/omnidevs_comic3.jpg" width="800" />
</a>
</div>
<p>
Stay tuned for the next instalment!</p>
<p>
Previous strip: <a href="https://arjan-tijms.omnifaces.org/2019/11/the-productive-standup.html">The productive standup</a> Next Strip: <a href="https://arjan-tijms.omnifaces.org/2020/09/hiring-right-people.html">Hiring the right people
</a>Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-72868650425251819552020-05-04T09:07:00.004-07:002021-12-06T15:08:24.124-08:00Implementation components used by Jakarta EE servers A while ago we looked at which <a href="https://arjan-tijms.omnifaces.org/2014/05/implementation-components-used-by.html">implementation components the various Java EE servers</a> were using. At the time this concerned mostly Java EE 6 servers, with a few Java EE 7 ones thrown in for good measure.
<p>
Fast forward 6 years, and we have arrived at Jakarta EE 8 essentially (a <a href="https://blogs.oracle.com/javamagazine/transition-from-java-ee-to-jakarta-ee">re-licensing of Java EE 8</a>). Most servers from the previous instalment have Jakarta EE 8 versions out. WebLogic has its Java EE 8 version officially out, with a Jakarta EE 8 version coming soon (there is no technical difference between these two really). TomEE has started to implement Java EE 8 and in its latest version has gotten quite far, but is not there yet. Resin remained at Java EE 6 with seemingly <a href="https://groups.google.com/forum/#!topic/caucho-resin/hjzgGyolZb8">no plans to update these</a>. JOnAS has <a href="https://mail.ow2.org/wws/arc/jonas/2017-05/msg00003.html">disappeared off the face of the earth</a>, and so has <a href="https://issues.apache.org/jira/browse/GERONIMO-6714">Geronimo as server</a> (though as a <a href="http://apache-geronimo.328035.n3.nabble.com/VOTE-Apache-Geronimo-Specs-JCDI-2-0-.-2-Annotation-1-3-1-3-AtInject-1-0-1-2-Interceptor-1-2-1-2-JSON3-td3993442.html">provider of APIs and their implementations</a> it has stayed alive).
<p>
Without further ado, here's the matrix of Java EE 8/Jakarta EE 8 implementation components used by Java EE/Jakarta EE servers:
<style>
.SpecTable a, .FooterTable a:hover {
color: black;
}
table.SpecTable {
text-align: center
}
td.RedHat, th.RedHat {
background: repeating-linear-gradient(
90deg,
#ffebe6,
#ffc2b3 100%
);
}
td.Eclipse, th.Eclipse {
background: repeating-linear-gradient(
90deg,
#ffe0b3,
#ffcc80 100%
);
}
td.Oracle, th.Oracle {
background: repeating-linear-gradient(
90deg,
#F5F5F5,
#C0C0C0 100%
);
}
td.Apache, th.Apache {
background: repeating-linear-gradient(
90deg,
#d6f5d6,
#adebad 100%
);
}
td.IBM, th.IBM {
background: repeating-linear-gradient(
90deg,
#e6ccff,
#cc99ff 100%
);
}
td.TMax, th.TMax {
background: repeating-linear-gradient(
90deg,
#cce0ff,
#99c2ff 100%
);
}
td.spec, th.spec {
background: repeating-linear-gradient(
90deg,
#F8F8F8,
#F5F5F5 100%
);
}
</style>
<p>
<div style="overflow:auto;">
<small><small>
<table border="1" style="width:100%; color: black" class="SpecTable">
<tr>
<th class="spec"><i>Vendor</i></th>
<th class="RedHat">Red Hat</th>
<th class="Eclipse">Eclipse</th>
<th class="Oracle">Oracle</th>
<th class="Apache">Apache</th>
<th class="IBM">IBM</th>
<th class="TMax">TMax</th>
<tr>
<tr>
<th class="spec"><i>AS</i></th>
<th class="RedHat"><a href="https://wildfly.org">WildFly</a></th>
<th class="Eclipse"><a href="https://projects.eclipse.org/projects/ee4j.glassfish">GlassFish</a></th>
<th class="Oracle"><a href="https://oracle.com/middleware/technologies/weblogic.html">WebLogic</a></th>
<th class="Apache"><a href="http://tomee.apache.org">TomEE+</a></th>
<th class="IBM"><a href="https://openliberty.io">Open Liberty</a></th>
<th class="TMax"><a href="https://technet.tmaxsoft.com/ko/front/main/main.do">JEUS</a></th>
<tr>
<tr>
<th style="white-space:nowrap" class="spec"><i>Spec/Version</i></th>
<th class="RedHat">19</th>
<th class="Eclipse">5.1</th>
<th class="Oracle">14.1.1</th>
<th class="Apache">8.0.1</th>
<th class="IBM">20.0.0.4</th>
<th class="TMax">8-b266</th>
<tr>
<!-- Servlet -->
<tr>
<td style="white-space:nowrap" class="spec">
<b>Servlet</b></td>
<td class="RedHat"><a href="http://undertow.io">Undertow Servlet </a> 2.0.30 <br/> <a href="https://github.com/undertow-io/undertow/tree/master/servlet"><small>source</small></a> </td>
<td class="Eclipse">Tomcat derivative & <a href="https://grizzly.java.net">Grizzly</a></td>
<td class="Oracle">Nameless internal</td>
<td class="Apache">Tomcat</td>
<td class="IBM">WAS WebContainer (part of open liberty) <br/> <small>8.1 / 1.0.39.cl200420200401-1714</small> <br/> <a href="https://github.com/OpenLiberty/open-liberty/commits/integration/dev/com.ibm.ws.webcontainer.servlet.4.0"><small>source</small></a> </td>
<td class="TMax">JEUS Servlet (part of JEUS) <br/> 8.0.0.2</small></td>
</tr>
<!-- ENTERPRISE BEANS -->
<tr>
<td class="spec"><b>Enterprise Beans</b></td>
<td class="RedHat">Nameless internal</td>
<td class="Eclipse">Nameless internal <small>(EJB-container)</small></td>
<td class="Oracle">Nameless internal</td>
<td class="Apache">OpenEJB</td>
<td class="IBM">Nameless internal</td>
<td class="TMax">Nameless internal</td>
</tr>
<!-- CONNECTORS -->
<tr>
<td class="spec"><b>Connectors</b></td>
<td class="RedHat"><a href="http://ironjacamar.org">IronJacamar 1.4.20</a></td>
<td class="Eclipse">Nameless internal (Connectors-runtime)</td>
<td class="Oracle">Nameless internal</td>
<td class="Apache">Geronimo Connector 3.1.4 <br/> <a href="https://github.com/apache/geronimo-txmanager/tree/trunk/geronimo-connector"><small>source</small></a> </td>
<td class="IBM">Nameless internal <br/> <a href="https://github.com/OpenLiberty/open-liberty/tree/integration/dev/com.ibm.ws.jca"><small>source</small></a> </td>
<td class="TMax">Nameless internal</td>
</tr>
<!-- AUTHENTICATION -->
<tr>
<td class="spec"><b>Authentication</b></td>
<td class="RedHat">
Part of <a href="https://wildfly-security.github.io/wildfly-elytron">Elytron</a> <br/>
1.11.2 <br/>
<a href="https://github.com/wildfly-security/wildfly-elytron/tree/master/auth/jaspi"> <small>source</small></a>
</td>
<td class="Eclipse">Jaspic provider framework (part of GlassFish) </td>
<td class="Oracle">Part of <a href="https://docs.oracle.com/en/middleware/standalone/weblogic-server/14.1.1.0/intro/security.html">WebLogic Security</a></td>
<td class="Apache">Part of Tomcat</td>
<td class="IBM">Nameless internal <br/> <a href="https://github.com/OpenLiberty/open-liberty/tree/integration/dev/com.ibm.ws.security.jaspic"> <small>source</small></a> </td>
<td class="TMax">Nameless internal</td>
</tr>
<!-- TRANSACTIONS -->
<tr>
<td class="spec"><b>Transactions</b></td>
<td class="RedHat"><a href="http://narayana.jboss.org">Narayana</a> <br/> <a href="https://github.com/jbosstm/narayana"> <small>source</small> </a></td>
<td class="Eclipse">Nameless internal</td>
<td class="Oracle">Nameless internal</td>
<td class="Apache">Geronimo Transaction 3.1.4 <br/> <a href="https://github.com/apache/geronimo-txmanager/tree/trunk/geronimo-transaction"><small>source</small></a> </td>
<td class="IBM">Nameless internal</td>
<td class="TMax">JEUS Transaction Manager (part of JEUS) <br/> 8.0.0.2 </td>
</tr>
<!-- MESSAGING -->
<tr>
<td class="spec"><b>Messaging</b></td>
<td class="Apache">
<a href="https://activemq.apache.org/components/artemis">ActiveMQ Artemis</a> 2.10.1 <br/> <a href="https://github.com/apache/activemq-artemis">source</a></td>
<td class="Eclipse">
<a href="https://eclipse-ee4j.github.io/openmq/">OpenMQ</a> <br/>
5.1.4 <br/>
<a href="https://github.com/eclipse-ee4j/openmq"><small>source</small></a>
</td>
<td class="Oracle"><a href="https://docs.oracle.com/en/middleware/standalone/weblogic-server/14.1.1.0/intro/jms.html">WebLogic JMS</a> <br/> </td>
<td class="Apache"><a href="http://activemq.apache.org/components/classic">ActiveMQ Classic</a> 5.15.10 <br/> <a href="https://github.com/apache/activemq"><small>source</small></a> </td>
<td class="IBM">
<a href="https://ibm.com/support/knowledgecenter/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/cwlp_messaging.html">Liberty messaging</a> <small>(part of open liberty)</small>
<br/> <small>1.0.39.cl200420200401-1714</small>
<br/> <a href="https://github.com/OpenLiberty/open-liberty/tree/integration/dev/com.ibm.ws.messaging.jms.2.0"><small>source</small></a> </td>
<td class="TMax">JEUS JMS (part of JEUS) <br/> 3.0.0 </td>
</tr>
<!-- CONCURRENCY -->
<tr>
<td class="spec"><b>Concurrency</b></td>
<td class="Eclipse">Concurrency RI <br/> 1.1.1 <br/> <a href="https://github.com/eclipse-ee4j/concurrency-ri"><small>source</small></a> </td>
<td class="Eclipse">Concurrency RI <br/> 1.1.1 <br/> <a href="https://github.com/eclipse-ee4j/concurrency-ri"><small>source</small></a> </td>
<td class="Oracle">Nameless Internal <small>(WebLogic concurrent</small>)</td>
<td class="Apache">Nameless Internal (part of OpenEJB-Core) <br/>
<a href="https://github.com/apache/tomee/tree/master/container/openejb-core/src/main/java/org/apache/openejb/threads"><small>source</small></a>
</td>
<td class="IBM">
Nameless Internal <br/>
<a href="https://github.com/OpenLiberty/open-liberty/tree/integration/dev/com.ibm.ws.concurrent"><small>source</small>
</td>
<td class="TMax">JEUS Concurrent (part of JEUS) <br/> 8.0.0.2 </td>
</tr>
<!-- WEBSOCKET -->
<tr>
<td class="spec"><b>WebSocket</b></td>
<td class="RedHat">
<a href="http://undertow.io">Undertow WebSockets JSR </a> <br/>
2.0.30 <br/>
<a href="https://github.com/undertow-io/undertow/tree/master/websockets-jsr"><small>source</small></a> </td>
<td class="Eclipse"><a href="https://eclipse-ee4j.github.io/tyrus">Tyrus </a> <br/>1.15 <br/> <a href="https://github.com/eclipse-ee4j/tyrus"><small>source</small></a> </td>
<td class="Eclipse"><a href="https://eclipse-ee4j.github.io/tyrus/">Tyrus </a> <br/> 1.15 <br/> <a href="https://github.com/eclipse-ee4j/tyrus"><small>source</small></a> </td>
<td class="Apache">Tomcat WebSocket (part of Tomcat) <br/> 9.0.30 <br/> <a href="https://github.com/apache/tomcat/tree/master/java/org/apache/tomcat/websocket">source</a> </td>
<td class="IBM">
Liberty WebSocket (part of Open Liberty) <br/>
1.0.39.cl200420200401-1714 <br/>
<a href="https://github.com/OpenLiberty/open-liberty/tree/integration/dev/com.ibm.ws.wsoc">source</a> </td>
<td class="TMax">JEUS WebSocket (part of JEUS) </br> 8.0.0.2 </td>
</tr>
<!-- CDI -->
<tr>
<td class="spec"><b>CDI</b></td>
<td class="RedHat"><a href="http://weld.cdi-spec.org">Weld</a> <br/>3.1.3 <br/><a href="https://github.com/weld"><small>source</small></a> </td>
<td class="RedHat"><a href="http://weld.cdi-spec.org">Weld</a> <br/>3.0.0 <br/><a href="https://github.com/weld"><small>source</small></a></td>
<td class="RedHat"><a href="http://weld.cdi-spec.org">Weld</a> <br/>3.1.0 <br/><a href="https://github.com/weld"><small>source</small></a></td>
<td class="Apache"><a href="https://openwebbeans.apache.org">Open WebBeans</a> <br/>2.0.12 <br/> <a href="https://github.com/apache/openwebbeans"><small>source</small></a></td>
<td class="RedHat"><a href="http://weld.cdi-spec.org">Weld</a> <br/> 3.1.1 <br/><a href="https://github.com/weld"><small>source</small></a></td>
<td class="RedHat"><a href="http://weld.cdi-spec.org">Weld</a> <br/> 3.1.2 <br/><a href="https://github.com/weld"><small>source</small></a></td>
</tr>
<!-- VALIDATION -->
<tr>
<td class="spec"><b>Validation</b></td>
<td class="RedHat">
<a href="http://hibernate.org/validator">Hibernate Validator </a> <br/> 6.0.18 <br/> <a href="https://github.com/hibernate/hibernate-validator"><small>source</small></a> </td>
<td class="RedHat">
<a href="http://hibernate.org/validator">Hibernate Validator </a> <br/> 6.0.10 <br/> <a href="https://github.com/hibernate/hibernate-validator"><small>source</small></a> </td>
<td class="RedHat">
<a href="http://hibernate.org/validator">Hibernate Validator </a> 6.0.16 <br/> <a href="https://github.com/hibernate/hibernate-validator"><small>source</small></a> </td>
<td class="Apache">
<a href="https://github.com/apache/bval">BVal</a> <br/> 2.0.3 <br/> <a href="https://github.com/apache/bval"><small>source</small></a> </td>
<td class="RedHat">
<a href="http://hibernate.org/validator">Hibernate Validator </a> <br/> 6.1.1 <br/> <a href="https://github.com/hibernate/hibernate-validator"><small>source</small></a> </td>
<td class="RedHat">
<a href="http://hibernate.org/validator">Hibernate Validator </a> <br/> 6.1.0 <br/> <a href="https://github.com/hibernate/hibernate-validator"><small>source</small></a> </td>
</tr>
<!-- REST -->
<tr>
<td rowspan="2" class="spec"><b>REST</b></td>
<td rowspan="2" class="RedHat"><a href="https://resteasy.github.io">RESTEasy</a> <br/>3.11 <br/> <a href="https://github.com/resteasy/Resteasy"><small>source</small></a> </td>
<td rowspan="2" class="Eclipse"><a href="https://eclipse-ee4j.github.io/jersey">Jersey</a> <br/> 2.28 <br/> <a href="https://github.com/eclipse-ee4j/jersey"><small>source</small></a> </td>
<td rowspan="2" class="Eclipse"><a href="https://eclipse-ee4j.github.io/jersey">Jersey</a> <br/> 2.29 <br/> <a href="https://github.com/eclipse-ee4j/jersey"><small>source</small></a> </td>
<td rowspan="2" class="Apache"><a href="https://cxf.apache.org">CXF</a> <br/> 3.3.4 <br/> <a href="https://github.com/apache/cxf/tree/master/rt/frontend/jaxrs"><small>source</small></a> </td>
<td class="RedHat"><a href="https://resteasy.github.io">RESTEasy</a> <br/><small>(for EE 9)</small><br/> <a href="https://github.com/resteasy/Resteasy"><small>source</small></a> </td>
<td rowspan="2" class="Eclipse"><a href="https://eclipse-ee4j.github.io/jersey">Jersey</a> <br/> 2.29.1 <br/> <a href="https://github.com/eclipse-ee4j/jersey"><small>source</small></a> </td>
</tr>
<!-- REST 2 -->
<tr>
<td class="Apache"><a href="https://cxf.apache.org">CXF</a> <br/> 3.3.3 <small>(for EE 8)</small><br/> <a href="https://github.com/apache/cxf/tree/master/rt/frontend/jaxrs"><small>source</small></a> </td>
</tr>
<!-- PERSISTENCE -->
<tr>
<td class="spec"><b>Persistence</b></td>
<td class="RedHat"><a href="http://hibernate.org/orm">Hibernate</a> <br/>5.3.5.15 <br/><a href="https://github.com/hibernate/hibernate-orm"><small>source</small></a></td>
<td class="Eclipse"><a href="https://eclipse.org/eclipselink">Eclipselink</a> <br/>2.7.4 <br/> <a href="https://github.com/eclipse-ee4j/eclipselink"><small>source</small></a></td>
<td class="Eclipse"><a href="https://eclipse.org/eclipselink">Eclipselink</a> <br/>2.7.6 <br/> <a href="https://github.com/eclipse-ee4j/eclipselink"><small>source</small></a></td>
<td class="Apache"><a href="https://openjpa.apache.org">OpenJPA</a> <br/>3.1.0 <br/> <a href="https://github.com/apache/openjpa"><small>source</small></a> </td>
<td class="Eclipse"><a href="https://eclipse.org/eclipselink">Eclipselink</a> <br/>2.7.6 <br/> <a href="https://github.com/eclipse-ee4j/eclipselink"><small>source</small></a></td>
<td class="Eclipse"><a href="https://eclipse.org/eclipselink">Eclipselink</a> <br/>2.7.5 <br/> <a href="https://github.com/eclipse-ee4j/eclipselink"><small>source</small></a></td>
</tr>
<!-- FACES -->
<tr>
<td class="spec"><b>Faces</b></td>
<td class="Eclipse">
<a href="https://projects.eclipse.org/projects/ee4j.mojarra">Mojarra</a> <br/> 2.3.9.SP06 <br/> <a href="https://github.com/eclipse-ee4j/mojarra"><small>source</small></a>
</td>
<td class="Eclipse">
<a href="https://projects.eclipse.org/projects/ee4j.mojarra">Mojarra</a> <br/> 2.3.9 <br/> <a href="https://github.com/eclipse-ee4j/mojarra"><small>source</small></a>
</td>
<td class="Eclipse">
<a href="https://projects.eclipse.org/projects/ee4j.mojarra">Mojarra</a> <br/> 2.3.14 <br/> <a href="https://github.com/eclipse-ee4j/mojarra"><small>source</small></a>
</td>
<td class="Apache"><a href="http://myfaces.apache.org">MyFaces </a> <br/> 2.3.6 <br/> <a href="https://github.com/apache/myfaces"><small>source</small></a> </td>
<td class="Apache"><a href="http://myfaces.apache.org">MyFaces </a> <br/> 2.3.6 <br/> <a href="https://github.com/apache/myfaces"><small>source</small></a> </td>
<td class="Eclipse"><a href="https://projects.eclipse.org/projects/ee4j.mojarra">Mojarra</a> <br/> 2.3.9 <br/> <a href="https://github.com/eclipse-ee4j/mojarra"><small>source</small></a> </td>
</tr>
<!-- JSON BINDING -->
<tr>
<td class="spec"><b>JSON Binding</b></td>
<td class="Eclipse"> Yasson 1.0.5 <br/> <a href="https://github.com/eclipse-ee4j/yasson"><small>source</small></a> </td>
<td class="Eclipse"> Yasson 1.0.3 <br/> <a href="https://github.com/eclipse-ee4j/yasson"><small>source</small></a> </td>
<td class="Eclipse"> Yasson 1.0.3 <br/> <a href="https://github.com/eclipse-ee4j/yasson"><small>source</small></a> </td>
<td class="Apache"> <a href="https://johnzon.apache.org">Johnzon</a> 1.1.13 <br/> <a href="https://github.com/apache/johnzon"><small>source</small></a> </td>
<td class="Eclipse"> Yasson 1.0.6 <br/> <a href="https://github.com/eclipse-ee4j/yasson"><small>source</small></a> </td>
<td class="Eclipse"> Yasson 1.0.6 <br/> <a href="https://github.com/eclipse-ee4j/yasson"><small>source</small></a> </td>
</tr>
<!-- EXPRESSION LANGUAGE -->
<tr>
<td class="spec"><b>Expression Language</b></td>
<td class="Eclipse">EL RI <br/> 3.0.3.jbossorg-2 <br/> <a href="https://github.com/eclipse-ee4j/el-ri/tree/master/impl">source</a></td>
<td class="Eclipse">EL RI <br/> 3.0.2 <br/> <a href="https://github.com/eclipse-ee4j/el-ri/tree/master/impl">source</a></td>
<td class="Eclipse">EL RI <br/> 3.0.2 <br/> <a href="https://github.com/eclipse-ee4j/el-ri/tree/master/impl">source</a></td>
<td class="Apache">Jasper EL 9.0.30 (part of Tomcat) <br/> <a href="https://github.com/apache/tomcat/tree/master/java/org/apache/el">source</a> </td>
<td class="Apache">Jasper EL 3.0.16(?) <br/> <a href="https://github.com/apache/tomcat/tree/master/java/org/apache/el">source</a> </td>
<td class="Eclipse">EL RI <br/> 3.0.0 <br/> <a href="https://github.com/eclipse-ee4j/el-ri/tree/master/impl">source</a></td>
</tr>
<!-- MAIL -->
<tr>
<td class="spec"><b>Mail</b></td>
<td class="Eclipse"><a href="https://eclipse-ee4j.github.io/mail">Jakarta Mail Impl </a> <br/>1.6.4 <br/> <a href="https://github.com/eclipse-ee4j/mail"><small>source</small></a> </td>
<td class="Eclipse"><a href="https://eclipse-ee4j.github.io/mail">Jakarta Mail Impl </a> <br/>1.6.3 <br/> <a href="https://github.com/eclipse-ee4j/mail"><small>source</small></a> </td>
<td class="Eclipse"><a href="https://eclipse-ee4j.github.io/mail">Jakarta Mail Impl </a> <br/>1.6.2 <br/> <a href="https://github.com/eclipse-ee4j/mail"><small>source</small></a> </td>
<td class="Apache">Geronimo JavaMail</td>
<td class="Eclipse"><a href="https://eclipse-ee4j.github.io/mail">Jakarta Mail Impl </a> <br/>1.6.2 <br/> <a href="https://github.com/eclipse-ee4j/mail"><small>source</small></a> </td>
<td class="Eclipse"><a href="https://eclipse-ee4j.github.io/mail">Jakarta Mail Impl </a> <br/>1.6.2 <br/> <a href="https://github.com/eclipse-ee4j/mail"><small>source</small></a> </td>
</tr>
<!-- SECURITY -->
<tr>
<td class="spec"><b>Security</b></td>
<td class="Eclipse">Soteria <br/> 1.0.1-jbossorg-1 <br/> <a href="https://github.com/eclipse-ee4j/soteria"><small>source</small></a> </td>
<td class="Eclipse">Soteria <br/> 1.0 <br/> <a href="https://github.com/eclipse-ee4j/soteria"><small>source</small></a> </td>
<td class="Eclipse">Soteria <br/> 1.0 <br/> <a href="https://github.com/eclipse-ee4j/soteria"><small>source</small></a> </td>
<td class="Apache">TomEE Security <br/> <small>TomEE 9m7</small></td>
<td class="IBM">
Nameless Internal <br/>
<a href="https://github.com/OpenLiberty/open-liberty/tree/integration/dev/com.ibm.ws.security.javaeesec.cdi"><small>source</small>
</td>
<td class="Eclipse">Soteria <br/> 1.1-b01-SNAPSHOT (modified) <br/> <a href="https://github.com/eclipse-ee4j/soteria"><small>source</small></a> </td>
</tr>
<!-- BATCH -->
<tr>
<td class="spec"><b>Batch</b></td>
<td class="RedHat">JBeret <br/> 1.3.5 <br/> <a href="https://github.com/jberet/jsr352"><small>source</small></a></td>
<td class="IBM">jbatch FRI <br/> 1.0.3 <br/><a href="https://github.com/WASdev/standards.jsr352.jbatch"><small>source</small></a> </td>
<td class="IBM">jbatch FRI <br/> 1.0.3 <br/><a href="https://github.com/WASdev/standards.jsr352.jbatch"><small>source</small></a> </td>
<td class="Apache"><a href="https://geronimo.apache.org/batchee">Geronimo BatchEE</a> <br/> 0.5-incubating <br/> <a href="https://github.com/apache/geronimo-batchee"><small>source</small></a> </td>
<td class="IBM">jBatch FRI <br/> 1.0.16 (internal copy) <br/>
<a href="https://github.com/OpenLiberty/open-liberty/tree/integration/dev/com.ibm.jbatch.container"><small>source</small>
</td>
<td class="IBM">jbatch FRI <br/> 1.1-SNAPSHOT <br/><a href="https://github.com/WASdev/standards.jsr352.jbatch"><small>source</small></a> </td>
</tr>
</table>
</small></small>
</div>
<p>
Each color a component has reflects the vendor with that color in the header. Essentially there's four vendors creating separate and re-usable Jakarta EE components:
<table border="1" style="width:10%; color: black" class="SpecTable">
<tr>
<td class="RedHat">Red Hat</td>
</tr>
<tr>
<td class="Eclipse">Eclipse</td>
</tr>
<tr>
<td class="Apache">Apache</td>
</tr>
<tr>
<td class="IBM">IBM</td>
</tr>
</tr>
</table>
<p>
Oracle and TMaxSoft do create components that implement Jakarta EE APIs, but only use them within their own server products. Things are however not that clear cut. As can be seen in the <a href="https://arjan-tijms.omnifaces.org/2014/05/implementation-components-used-by.html">previous instalment</a>, all the components that are now Eclipse components were Oracle components before. This is because <a href="https://blogs.oracle.com/javamagazine/transition-from-java-ee-to-jakarta-ee">Oracle donated all of its reusable components to the Eclipse Foundation</a>. Although IBM only directly produces one reusable component (jBatch FRI), it did not too long ago acquire Red Hat. This means all Red Hat components are essentially IBM components now, just as when the Sun components became Oracle components after Oracle acquired Sun.
<p>
If we look at the servers itself, we see that only TomEE exclusively uses components from a single vendor; its own vendor Apache. WildFly uses many components from its own vendor Red Hat, but uses components for Faces, JSON, Concurrency and Security among others from Eclipse. WildFly uses a single Apache component, namely ActiveMQ Artemis. This however used to be Red Hat's own component, HornetQ, which it donated to Apache in order to merge the existing ActiveMQ and HornetQ communities and <a href="https://planet.jboss.org/post/hornetq_apache_donation_and_apache_artemis_1_0_0_release">together work on the next generation message broker</a>.
<p>
GlassFish uses most components from Eclipse, its own vendor, two from Red Hat and one from IBM. This is however not randmom. As the former RI (reference implementation) of Java EE, it incorporated all the RI components. Since Red Hat was leading two specs, and IBM one, it used the components from those spec leaders. In Jakarta EE the concept of the RI has been done away with and has been replaced by <b>compatible implementations</b>, of which there always needs to be at least one. Since GlassFish is no longer an RI, its community could potentially develop Eclipse implementations of CDI, Validation and Batch. At least for the former a development that could lead to this <a href="https://github.com/payara/Payara/issues/4558">is being considered</a> by Payara.
<p>
Derivative servers were not included in the table, as they have the same components as the server they are derived from (albeit these components could be in different versions). This includes Payara and Cosminexus (Hitachi Application Server), and JBoss EAP. It's perhaps interesting to note that Payara and Hitachi are <a href="https://projects.eclipse.org/projects/ee4j.glassfish/who">joint co-leaders of the GlassFish project</a> and devote a significant amount of resources to further the upstream GlassFish project together with former owner Oracle.
<p>
Also excluded is our own Jakarta EE runtime, <a href="https://piranha.cloud">Piranha</a>. This is because at the time of writing Piranha is far from ready. Via the OmniFaces project Piranha does introduce new reusable Jakarta EE components; for <a href="https://github.com/omnifaces/eleos">Jakarta Authentication</a> and <a href="https://github.com/omnifaces/exousia">Jakarta Authorization</a>, which until so far hadn't been produced by anyone (JOnAS however once did start development for a reusable Jakarta Authentication/JASPIC component).
<br/>
<p>
<i>Arjan Tijms</i>Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com1tag:blogger.com,1999:blog-4498889353428710313.post-73854466738471962162020-04-12T14:04:00.000-07:002020-04-12T14:04:40.496-07:00New Jakarta EE 8 Certified server: Primeton AppServer V7Somewhat as a surprise, a company called Primeton Information Technologies, Inc recently <a href="https://jakarta.ee/compatibility https://github.com/jakartaee/jakarta.ee/issues/702">filed a certification request</a> for a new <a href="https://jakarta.ee/compatibility">Jakarta EE 8 compliant server</a> called Primeton AppServer V7.
<p>
In this blog we're going to take a quick look at what this server entails. As <a href="https://jakarta.ee">Jakarta EE</a> is a very complete platform, from scratch implementations are rare to basically non-existent, so it's interesting to see what's exactly in Primeton AppServer V7.
<p>
Within a Jakarta EE certification request, a link where the product (or a trial thereof) can be downloaded is mandatory, and Primeton indeed <a href="http://primeton.com/products/pas">provided one</a>. Today's Internet users normally have it easy. One clicks on a download link, and the software effortlessly transfers to your machine. Thanks to 500mbit+ speeds which are becoming increasingly common in this part of the world, most downloads take mere seconds. If you're from a certain age though, you may remember how different this was in the late 80s and early 90s. Dial-up modems that would fail halfway (or not rarely, when at 99%), and a download of 1MB or less taking hours and hours.
<p>
The Primeton download brought some of these nostalgic memories back:
<p>
<b>Challenge 1:</b> Initially your are presented with a challenge: a box in which you have to enter something, and you have to type something back to get something again:
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDSOUVesZYw9yaogCBms3QT1DilQ2XCBv3VymhBiB-A2H_UhqFz2ESNs2yQ9_nsVLTe7hZ_V3C-nKI3MNSz8n0_s6P-1RLGPYf8vehzmUwsp7c1ap-HCKCdMXD-IGuYCY3xlIb3BVN6G93/s1600/78839522-f2c3f400-79f8-11ea-8549-3666b846dde5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDSOUVesZYw9yaogCBms3QT1DilQ2XCBv3VymhBiB-A2H_UhqFz2ESNs2yQ9_nsVLTe7hZ_V3C-nKI3MNSz8n0_s6P-1RLGPYf8vehzmUwsp7c1ap-HCKCdMXD-IGuYCY3xlIb3BVN6G93/s1600/78839522-f2c3f400-79f8-11ea-8549-3666b846dde5.png" data-original-width="1270" data-original-height="404" /></a></div>
<p>
Puzzling... after some attempts and with the help of Chrome translate, it appeared to be a phone number. Of course, only Chinese numbers are accepted, and Chinese numbers are fairly difficult to obtain from outside China (a problem which we'll stumble upon once more later). Luckily the kind people at Primeton agreed to reduce the difficulty of this challenge and changed the challenge screen to:
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlKEejzUblQNmUx0yWsPdnFJUMMZ0QmKKcVEoc0UCxY40JPUV4b3bKV6uKMMkeW5hqynOhmgBOiLBTfu5D_UeikkcZa9F2-esV8wO_bt9IcWOP_yzWfEh1xcYzwLUfvZWyEmtvOYZe6E5b/s1600/Screenshot+2020-04-12+at+19.33.52.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlKEejzUblQNmUx0yWsPdnFJUMMZ0QmKKcVEoc0UCxY40JPUV4b3bKV6uKMMkeW5hqynOhmgBOiLBTfu5D_UeikkcZa9F2-esV8wO_bt9IcWOP_yzWfEh1xcYzwLUfvZWyEmtvOYZe6E5b/s1600/Screenshot+2020-04-12+at+19.33.52.png" data-original-width="1600" data-original-height="360" /></a></div>
This one is seemingly much easier, although appearances can be deceptive. Typing in an email address would give "提示 手机号码不能为空!" as response. Puzzling... luckily the kind people from Primeton were again willing to provide a hint. The intend is to do a hard browser refresh. After doing that, a frantic countdown started. Only 59 seconds to provide a response! Will the email reply be in time? While the timer was frantically counting down, I was frantically refreshing my email client. With only 12 seconds left on the timer, the email arrived with a code! I quickly copied the code, went back to the challenge screen and with some 8 seconds left on the timer it accepted my code, and took me to the second challenge.
<p>
<b>Challenge 2:</b> a new screen with multiple boxes, some of which drop-downs. How to beat this one? The first was a numerical box. After some trial and error it appeared it wanted a number of 11 digits, starting with 134 to 139, or 150 to 159, and some more. I opted for "13412341234", and hey ho, it was happy with that. Sub-challenge 2.1 beaten! But the other boxes proved more difficult to pass. No matter what I put into them, it kept giving me back "提示 请检查姓名,公司字段". Did it want only Chinese characters? Or only English? Perhaps of a certain length? Eventually it appeared that the secret combination one had to enter was hard refreshing the page again. It's not super clear how the system exactly detects this, but there you have it. It was now fully happy, and after leaving me in anticipation for a few seconds it provided me with the third challenge: a mysterious link and a code. (hint: the code is only for a short while on your screen, so copy it right away when you get it).
<p>
<b>Challenge 3:</b> The link looked something like this: <i>https://pan.baidu.com/s/1TKf9B_puPZfDooooXXX</i> (made up link), while the code looked this this: <i>a8op</i> (again, made up code). Entering the link, the mysterious website asked for the code. I expected this to involve a challenge as well, but somewhat to my surprise the code was accepted without an additional challenge. I was now presented with what appeared to be a download page:
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwxrTk9dH4UWDdsE8_rsd8EU3MtdP5qD9ccGl3cUkwDb1s-NADcZal7vTebaVwXdcwggwTrzXdPeSY4mizb8CgTtBdroKopJzzYqVFbLay5mvku7tK_rfMItxseJIdXIR13RU59LdaYHlF/s1600/Screenshot+2020-04-11+at+23.57.41.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwxrTk9dH4UWDdsE8_rsd8EU3MtdP5qD9ccGl3cUkwDb1s-NADcZal7vTebaVwXdcwggwTrzXdPeSY4mizb8CgTtBdroKopJzzYqVFbLay5mvku7tK_rfMItxseJIdXIR13RU59LdaYHlF/s1600/Screenshot+2020-04-11+at+23.57.41.png" data-original-width="1600" data-original-height="1038" /></a></div>
Only the download page was just a teaser. You can't directly download something from it, but you again have to go through a challenge, the fourth one.
<p>
<b>Challenge 4:</b> after some trial and error, it appears the challenge is to create an account. Initially this seems simple. After all, we create accounts all the time everywhere. How hard can this possible be? Well, the answer is: very hard, or in this case, very challenging. Where sites such as Reddit once wowed people all over the world in simplifying account creation as much as possible, Baidu wowed people by making it as hard as possible (for people outside China, that is). After being stuck for quite some time on this challenge, I basically admitted defeat. The key problem is that you need a Chinese phone number again, although there's a hidden registration form where you can provide numbers from countries like Nigeria or Korea, but unfortunately nothing from the EU. Luckily a Chinese friend could help me out, so I got an account. Yes, it's cheating a little. Having the account the site directed me to the fifth challenge; a riddle.
<p>
<b>Challenge 5:</b> the website presented me the following riddle: "Yundetectservice.exe". In the time of Internet and Google, old fashioned riddles are not much of a challenge and it appeared that the riddle referred to having to install something called Baidu Netdisk. This appeared to be relatively simple. So I installed this, and logged-in to it using the aforementioned account. When you try to download something using the teaser screen shown above, the riddle would come up again, which you can just answer with "yes", upon which the Baidu Netdisk will take over the download, and then present you with the sixth challenge.
<p>
<b>Challenge 6:</b> the Baidu Netdisk will display the file to be downloaded, keep you in suspension for a few seconds, then present you with a cryptic message:
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI0B7sLrs7JGP2sFzymBqlM-ogUxM1g18vGex2GyP1QuAYpzpFBzz_ROAEECYwsIxRx11Spf62uWUZfjAQBTKVvuJbDn21KBId4Gy2JSKaUeb9OALzGLVevypSi5t53ni5sPRmPCbf2J4Q/s1600/Screenshot+2020-04-11+at+16.22.36+copy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI0B7sLrs7JGP2sFzymBqlM-ogUxM1g18vGex2GyP1QuAYpzpFBzz_ROAEECYwsIxRx11Spf62uWUZfjAQBTKVvuJbDn21KBId4Gy2JSKaUeb9OALzGLVevypSi5t53ni5sPRmPCbf2J4Q/s1600/Screenshot+2020-04-11+at+16.22.36+copy.png" data-original-width="1600" data-original-height="226" /></a></div>
After struggling with this for quite some time, it appeared the Baidu Netdisk is just a decoy. It's not a challenge one can solve. Instead, you have to backtrack to after challenge 4, and first copy the file you want to download to the private cloud storage of the account that you created. After you've done that, you can proceed to the next challenge, which is how to get it off of that account.
<p>
<b>Challenge 7:</b> after puzzling for a bit on this one, it appeared you need to connect your Baidu account to a service called <i>multcloud.com</I>. There's a funny little sub-challenge here, where you need to create a folder on your Baidu cloud storage called "lin1118" and move whatever you want to download to there. The challenge again tries to throw up some decoys, like making you belief you can transfer the file to another cloud storage, like e.g. Google Drive, but this is again just a decoy. If you look closely, you can obtain a public share link to the file you want to download, which presents you with a download icon on its turn that actually starts to download!
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifbtcu1mm6hKsxwU1YUz2QBmllDkKQXYCY3wFDxFdKXs5mUm31q3xG0UxGNFfrUg71DAh_UAPVYrVBQK5vcD_8_L-Tke9PdLzremDj6RKjoOWP39qcHmPr_Y8P2BIO-42iVI84yhKd3AR1/s1600/Screenshot+2020-04-11+at+23.54.42.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifbtcu1mm6hKsxwU1YUz2QBmllDkKQXYCY3wFDxFdKXs5mUm31q3xG0UxGNFfrUg71DAh_UAPVYrVBQK5vcD_8_L-Tke9PdLzremDj6RKjoOWP39qcHmPr_Y8P2BIO-42iVI84yhKd3AR1/s1600/Screenshot+2020-04-11+at+23.54.42.png" data-original-width="1600" data-original-height="775" /></a></div>
<p>
But what fun would it be if it ended here so easily? There's a plot twist when the download suddenly stops! Resuming it will download maybe 200kb, maybe a whopping 2MB even, but never really more. It's throwing up a final challenge for you, the eighth one.
<p>
<b>Challenge 8:</b> getting the download to continue. Puzzling on this for a while using several different browsers, I finally beat this challenge using a download manager on Windows called Internet Download Manager (IDK). After installing this and attempting the download again, it will take it over and... is accepted by our game master and finally, finally allows us to download the file:
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyg9gSIGWacjK4RVkpJ2sfO-dsTZFXhBzzBaxRBBSumgyFe-1uPRasbYyFOyxRDqWtGZt0ZZAwwPofyCAC_J5oe4gL70modzkMnFoWVWSWcbtz1QjrFftPBpCL6IpSoM-Is74pihags092/s1600/Screenshot+2020-04-12+at+00.03.44.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyg9gSIGWacjK4RVkpJ2sfO-dsTZFXhBzzBaxRBBSumgyFe-1uPRasbYyFOyxRDqWtGZt0ZZAwwPofyCAC_J5oe4gL70modzkMnFoWVWSWcbtz1QjrFftPBpCL6IpSoM-Is74pihags092/s1600/Screenshot+2020-04-12+at+00.03.44.png" data-original-width="1032" data-original-height="554" /></a></div>
<p>
Now that was interesting! Who said downloading a file is boring?
<p>
Having spend nearly all my free time on this funny, but indeed time consuming challenge, I took a quick look at the archive. Inside are some installer scripts and a resources folder. In "<i>resources/as_comps/</I>" there's what seems to be the actual Jakarta EE 8 server: "<i>pas-7.0.0.zip</I>":
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQAWhWSsq4ErQaAnLxO8-4oeSYTjWZcWi0mcJ2l4PNMweNCoxJvQpWOV6R1AoQlbsSMUWqEyTFPS-BtWfptKt_Eb31c8SuJp1r9NXTeHxshVJ7Ush5KxXigHHlYLjVSbkQ2CBXDtZN897V/s1600/2020-04-11-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQAWhWSsq4ErQaAnLxO8-4oeSYTjWZcWi0mcJ2l4PNMweNCoxJvQpWOV6R1AoQlbsSMUWqEyTFPS-BtWfptKt_Eb31c8SuJp1r9NXTeHxshVJ7Ush5KxXigHHlYLjVSbkQ2CBXDtZN897V/s1600/2020-04-11-3.png" data-original-width="1600" data-original-height="365" /></a></div>
<p>
Opening that one, reveals a (to me) very familiar layout:
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxwETWvO_UYKcfGxPFl4LCtqeVnN3-Z5ynb1bJa1J7aOXUzRC8wBlUfamZdwVayYCkhji6ZVDRFWKLtvZ0B3ct9EtbszW6nxpiKMegJoQtP50-KjpSvA6qI6WcWsqlLMwITUMX1-IRRFdS/s1600/2020-04-11-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxwETWvO_UYKcfGxPFl4LCtqeVnN3-Z5ynb1bJa1J7aOXUzRC8wBlUfamZdwVayYCkhji6ZVDRFWKLtvZ0B3ct9EtbszW6nxpiKMegJoQtP50-KjpSvA6qI6WcWsqlLMwITUMX1-IRRFdS/s1600/2020-04-11-2.png" data-original-width="1174" data-original-height="686" /></a></div>
That looks exactly like <a href="https://eclipse-ee4j.github.io/glassfish">GlassFish</a>. Looking into the folders some more, and specifically the "<i>/modules/</I>" folder confirms this to be GlassFish based:
<p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7_sCb3rRvTSmuJs4OTj5zLhzspQ3-tq_EV2Mh7Wd86biY_os9ZEO8wFg-CdTefhYxQukpju-SdK-XodCqtVjwPi5xGUCnDS1RqLARl01xilwLi8Fz71KzF7aM_z-bOUYEKel5CMcCmyHb/s1600/2020-04-11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7_sCb3rRvTSmuJs4OTj5zLhzspQ3-tq_EV2Mh7Wd86biY_os9ZEO8wFg-CdTefhYxQukpju-SdK-XodCqtVjwPi5xGUCnDS1RqLARl01xilwLi8Fz71KzF7aM_z-bOUYEKel5CMcCmyHb/s1600/2020-04-11.png" data-original-width="1600" data-original-height="920" /></a></div>
<p>
Now being GlassFish based is not that out of the ordinary in Jakarta EE land. The <a href="https://arjan-tijms.omnifaces.org/2015/05/necs-webotx-commercial-glassfish.html">"Japanese 3"</a> are all based on GlassFish as well, mostly having their own support channels and their own assortment of fixes. We're therefor very happy that Primeton has adopted GlassFish for its Chinese customers, and look forward to whatever this brings to the table concerning the <a href="https://github.com/eclipse-ee4j/glassfish">upstream GlassFish</a> maintenance.
<p>
Looking at the landscape of Jakarta EE compatible products, we now have 4 families of products: the GlassFish based ones, the JBoss based ones, JEUS and Open Liberty. It's expected that <a href="https://blogs.oracle.com/weblogicserver/announcing-oracle-weblogic-server-1411">WebLogic will join this group soon</a> (which is a unique implementation, though does share some bits with GlassFish), and hopefully Fujitsu will soon join as well (which is GlassFish based).
For now the landscape looks like this:
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPkn1eUUCQO_URwn55bnixfNa-G2ZAq8UJfpmvGDTB62DOZb09Bu-LNZGR54Omrpqo5k7_81-fEQwsphBl7LnO0azPhKz8RZSY3K-tQSC92fug00cdm8I1J6ZMxQKq1bLRODUhiE8-fAqg/s1600/Screenshot+2020-04-12+at+22.19.10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPkn1eUUCQO_URwn55bnixfNa-G2ZAq8UJfpmvGDTB62DOZb09Bu-LNZGR54Omrpqo5k7_81-fEQwsphBl7LnO0azPhKz8RZSY3K-tQSC92fug00cdm8I1J6ZMxQKq1bLRODUhiE8-fAqg/s1600/Screenshot+2020-04-12+at+22.19.10.png" data-original-width="1600" data-original-height="956" /></a></div>
<p>
<i>Arjan Tijms</i>
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-12234996299233339752020-01-14T14:36:00.000-08:002020-01-16T03:28:56.606-08:00Piranha 20.1.2 released!<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
<style>
/*! Color themes for Google Code Prettify | MIT License | github.com/jmblog/color-themes-for-google-code-prettify */
.prettyprint {
background: #FAFAFB;
font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace;
border: 1 !important;
border-radius: 5px;
font-size: 80%;
line-height: 1.4em;
margin-left: 10px;
padding-left: 8px !important;
}
.pln {
color: #333;
}
/* Specify class=linenums on a pre to get line numbering */
ol.linenums {
margin-top: 0;
margin-bottom: 0;
color: #cccccc;
}
li.L0,
li.L1,
li.L2,
li.L3,
li.L4,
li.L5,
li.L6,
li.L7,
li.L8,
li.L9 {
padding-left: 1em;
background-color: #fff;
list-style-type: decimal;
}
@media screen {
/* string content */
.str {
color: #183691;
}
/* keyword */
.kwd {
color: #a71d5d;
}
/* comment */
.com {
color: #969896;
}
/* type name */
.typ {
color: #0086b3;
}
/* literal value */
.lit {
color: #0086b3;
}
/* punctuation */
.pun {
color: #333;
}
/* lisp open bracket */
.opn {
color: #333;
}
/* lisp close bracket */
.clo {
color: #333;
}
/* markup tag name */
.tag {
color: #000080;
}
/* markup attribute name */
.atn {
color: #795da3;
}
/* markup attribute value */
.atv {
color: #183691;
}
/* declaration */
.dec {
color: #333;
}
/* variable name */
.var {
color: #008080;
}
/* function name */
.fun {
color: #900;
}
}
</style>
<a href="https://github.com/piranhacloud/piranha/releases/tag/v20.1.2">Piranha 20.1.2</a> has been released :)
<p>
In total <a href="https://github.com/piranhacloud/piranha/milestone/13?closed=1">59 issues</a> were done for this release, which mostly included work for Piranha Micro, but also includes improvements for Servlet compatibility among others. Note that Piranha is a work in progress and not yet ready for regular use, let alone production usage.
<p>
<a href="https://piranha.cloud">Piranha</a> itself is an upcoming Jakarta EE and MicroProfile runtime, currently in its early stages of development. Piranha's main goal is to use Jakarta APIs as much as possible as a library, using a flat class loader, and no concept of deploying applications, in other words without being an application server.
<p>
Piranha Micro however builds on the core Piranha foundation to deliver something that comes closer to a server; it can run a single application in archive form, albeit it can't undeploy and redeploy (this is on purpose). Specifically for embedded use it features an isolated class loader. Contrary to a traditional application server where an isolating class loader is used to run multiple applications in separation from each other, its purpose in Piranha is to isolate the archive from the application and all its classes and config files that embeds Piranha.
<p>
The jar files with Jakarta EE APIs and their implementations (for example the Jakarta Faces API and the Mojarra implementation) are handled in a somewhat unique way in Piranha Micro. The native method it internally uses is to load these via Maven, as demonstrated by the following snippet of internal code:
<pre class="prettyprint"><code class="lang-java">// Resolve all the dependencies that make up a Piranha runtime configuration
ConfigurableMavenResolverSystem mavenResolver = Maven.configureResolver();
configuration.getRepositoriesList().stream().forEach(repoUrl ->
mavenResolver.withRemoteRepo(createRepo(repoUrl)));
JavaArchive[] piranhaArchives =
mavenResolver
.workOffline(configuration.isOffline())
.resolve(configuration.getMergedDependencies())
.withTransitivity()
.as(JavaArchive.class);
// Make all those dependencies available to the Piranha class loader
ClassLoader piranhaClassLoader = getPiranhaClassLoader(piranhaArchives);</code>
</pre>
This means Piranha Micro is very flexible where it loads its own jars from. They can come from Maven central, an alternative remote repo, a local repo on the filesystem, the local .m2, etc. In Piranha 20.1.2 just a single Uber-jar is downloaded this way, but we'll refine this in the coming versions.
<p>
A related feature of Piranha is that jars loaded this way do not need to be stored and/or extracted on the filesystem first, but are loaded in-memory and directly passed to the custom class loader. Piranha Micro uses <a href="https://github.com/shrinkwrap/shrinkwrap">ShrinkWrap</a> archives for this, which has the additional advantages that when archives are created programmatically for embedded usage, Piranha Micro can run these directly.
<p>
Due to the early stage of development, Piranha Micro is currently only readily available via its Maven Arquillian connector. It can be seen in action in the <a href="https://github.com/javaee-samples/javaee7-samples">Java EE 7 Samples</a> project. For instance by cloning the project and typing the following:
<pre>
cd jaspic
mvn clean install -Ppiranha-embedded-micro
</pre>
<p>
<i>Arjan Tijms</i> Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-56793687779303533102020-01-09T12:46:00.000-08:002020-01-09T12:46:56.501-08:00Jan 2020 update: Piranha Micro getting more compatibleWe're currently hard at work with our <a href="https://piranha.cloud">Piranha</a> runtime implementation. Piranha is a new <a href="https://jakarta.ee">Jakarta EE</a> and <a href="https://microprofile.io">MicroProfile</a> runtime build from scratch. A distinguishing feature is that it's build from the ground up to use Jakarta EE and MicroProfile as a framework, which means without any (application) server bits. This is essentially how you would use a mock framework for Jakarta EE, except that with Piranha it's the actual runtime.
<p>
Piranha Micro takes the framework bits and with a minimal amount of glue code assembles these into what resembles a more traditional Jakarta EE Server (including an HTTP stack and the ability to run a single war archive). We'll be blogging about some interesting features this version of Piranha has soon. For now just a small status update, and that's that we're working hard on compatibility.
<p>
Last month we passed the <a href="https://wiki.eclipse.org/MicroProfile/Implementation#MP_JWT_implementations">MicroProfile JWT TCK</a> (which infers a certain minimal level of compatibility with CDI, Jakarta REST and MicroProfile Config). This month we've been looking at the <a href="https://github.com/javaee-samples/javaee7-samples">Java EE 7 samples</a> suite. This is an older, but still very valuable resource to both test implementations and learn how to use the Jakarta EE (Java EE) APIs.
<p>
We're happy to announce that Piranha Micro is passing all of the appropriate JASPIC (Jakarta Authentication) tests, and a large number of the Servlet and JAX-RS (Jakarta REST) ones. The JASPIC ones are particularly nice to pass, since Piranha uses the (largely) new OmniFaces implementation called <a href="https://github.com/omnifaces/eleos">Eleos</a> for this. Furthermore, the plain Servlet Security tests are under the hood powered by <a href="https://github.com/eclipse-ee4j/soteria">Eclipse Soteria</a> which is a compatible implementation (CI) of <a href="https://projects.eclipse.org/projects/ee4j.es">Jakarta Security</a>. To the best of our knowledge, this is another unique feature of Piranha (more about this in a later blog). Note that skipped tests for JASPIC are about EJB, which Piranha doesn't support yet.
<p>
The results from running Java EE 7 samples against the latest snapshot from master (<code><a href="https://github.com/piranhacloud/piranha">20.1.0-SNAPSHOT</a></code>) are shown below:
<br/>
<div style="font-size: 70%; line-height: 1">
<pre>
[INFO] Reactor Summary for Java EE 7 Sample: jaspic 1.0-SNAPSHOT:
[INFO]
[INFO] Java EE 7 Sample: jaspic - common .................. SUCCESS [ 1.044 s]
[INFO] Java EE 7 Sample: jaspic ........................... SUCCESS [ 0.284 s]
[INFO] Java EE 7 Sample: jaspic - basic-authentication .... SUCCESS [ 7.600 s]
[INFO] Java EE 7 Sample: jaspic - custom principal ........ SUCCESS [ 7.132 s]
[INFO] Java EE 7 Sample: jaspic - programmatic-authentication SUCCESS [ 4.075 s]
[INFO] Java EE 7 Sample: jaspic - lifecycle ............... SUCCESS [ 5.602 s]
[INFO] Java EE 7 Sample: jaspic - wrapping ................ SUCCESS [ 4.041 s]
[INFO] Java EE 7 Sample: jaspic - register-session ........ SUCCESS [ 5.756 s]
[INFO] Java EE 7 Sample: jaspic - async-authentication .... SUCCESS [ 0.272 s]
[INFO] Java EE 7 Sample: jaspic - Status codes ............ SUCCESS [ 5.535 s]
[INFO] Java EE 7 Sample: jaspic - dispatching ............. SUCCESS [ 5.546 s]
[INFO] Java EE 7 Sample: jaspic - dispatching JSF CDI ..... SUCCESS [ 4.076 s]
[INFO] Java EE 7 Sample: jaspic - ejb-propagation ......... SKIPPED [ 0.290 s]
[INFO] Java EE 7 Sample: jaspic - ejb-register-session .... SKIPPED [ 0.238 s]
[INFO] Java EE 7 Sample: jaspic - jacc-propagation ........ SUCCESS [ 5.495 s]
[INFO] Java EE 7 Sample: jaspic - invoke EJB and CDI ...... SKIPPED [ 0.228 s]
[INFO] ------------------------------------------------------------------------
</pre>
</div>
<div style="font-size: 70%; line-height: 1">
<pre>
[INFO] Reactor Summary for Java EE 7 Sample: servlet 1.0-SNAPSHOT:
[INFO]
[INFO] Java EE 7 Sample: servlet .......................... SUCCESS [ 0.754 s]
[INFO] Java EE 7 Sample: servlet - simple-servlet ......... SUCCESS [ 5.634 s]
[INFO] Java EE 7 Sample: servlet - async-servlet .......... SUCCESS [ 0.215 s]
[INFO] Java EE 7 Sample: servlet - servlet-filters ........ SUCCESS [ 3.674 s]
[INFO] Java EE 7 Sample: servlet - cookies ................ SUCCESS [ 4.096 s]
[INFO] Java EE 7 Sample: servlet - error-mapping .......... SUCCESS [ 4.037 s]
[INFO] Java EE 7 Sample: servlet - event-listeners ........ SUCCESS [ 4.178 s]
[INFO] Java EE 7 Sample: servlet - metadata-complete ...... SUCCESS [ 3.986 s]
[INFO] Java EE 7 Sample: servlet - web-fragment ........... SUCCESS [ 0.147 s]
[INFO] Java EE 7 Sample: servlet - nonblocking ............ SUCCESS [ 0.174 s]
[INFO] Java EE 7 Sample: servlet - protocol-handler ....... FAILURE [ 13.564 s]
[INFO] Java EE 7 Sample: servlet - resource-packaging ..... FAILURE [ 1.939 s]
[INFO] Java EE 7 Sample: servlet - file-upload ............ SUCCESS [ 3.205 s]
[INFO] Java EE 7 Sample: servlet - programmatic-registration SUCCESS [ 3.977 s]
[INFO] Java EE 7 Sample: servlet - security-basicauth ..... SUCCESS [ 4.037 s]
[INFO] Java EE 7 Sample: servlet - security-digest ........ SKIPPED [ 0.283 s]
[INFO] Java EE 7 Sample: servlet - security-form-based .... SUCCESS [ 4.133 s]
[INFO] Java EE 7 Sample: servlet - security-clientcert .... SKIPPED [ 0.394 s]
[INFO] Java EE 7 Sample: servlet - security-clientcert-jce SKIPPED [ 0.395 s]
[INFO] Java EE 7 Sample: servlet - security-programmatic .. SUCCESS [ 4.084 s]
[INFO] Java EE 7 Sample: servlet - security-deny-uncovered SUCCESS [ 3.997 s]
[INFO] Java EE 7 Sample: servlet - security-allow-uncovered SUCCESS [ 3.998 s]
[INFO] Java EE 7 Sample: servlet - security-annotated ..... FAILURE [ 3.975 s]
[INFO] Java EE 7 Sample: servlet - security-basicauth-omission SUCCESS [ 4.000 s]
[INFO] ------------------------------------------------------------------------
</pre>
</div>
<div style="font-size: 70%; line-height: 1">
<pre>
[INFO] Reactor Summary for Java EE 7 Sample: jaxrs 1.0-SNAPSHOT:
[INFO]
[INFO] Java EE 7 Sample: jaxrs ............................ SUCCESS [ 0.557 s]
[INFO] Java EE 7 Sample: jaxrs - async-client ............. SUCCESS [ 5.177 s]
[INFO] Java EE 7 Sample: jaxrs - async-server ............. FAILURE [ 4.058 s]
[INFO] Java EE 7 Sample: jaxrs - beanvalidation ........... FAILURE [ 4.178 s]
[INFO] Java EE 7 Sample: jaxrs - beanparam ................ SUCCESS [ 4.105 s]
[INFO] Java EE 7 Sample: jaxrs - client-negotiation ....... FAILURE [ 4.240 s]
[INFO] Java EE 7 Sample: jaxrs - db-access ................ FAILURE [ 3.567 s]
[INFO] Java EE 7 Sample: jaxrs - dynamicfilter ............ SUCCESS [ 4.885 s]
[INFO] Java EE 7 Sample: jaxrs - fileupload ............... SUCCESS [ 4.671 s]
[INFO] Java EE 7 Sample: jaxrs - filter ................... SUCCESS [ 4.226 s]
[INFO] Java EE 7 Sample: jaxrs - filter-interceptor ....... SUCCESS [ 0.186 s]
[INFO] Java EE 7 Sample: jaxrs - interceptor .............. SUCCESS [ 0.163 s]
[INFO] Java EE 7 Sample: jaxrs - invocation ............... SUCCESS [ 0.149 s]
[INFO] Java EE 7 Sample: jaxrs - invocation-async ......... SUCCESS [ 0.169 s]
[INFO] Java EE 7 Sample: jaxrs - jaxrs-client ............. FAILURE [ 4.458 s]
[INFO] Java EE 7 Sample: jaxrs - jaxrs-endpoint ........... SUCCESS [ 4.332 s]
[INFO] Java EE 7 Sample: jaxrs - jsonp .................... SUCCESS [ 4.377 s]
[INFO] Java EE 7 Sample: jaxrs - link ..................... SUCCESS [ 0.268 s]
[INFO] Java EE 7 Sample: jaxrs - mapping-exceptions ....... SUCCESS [ 4.113 s]
[INFO] Java EE 7 Sample: jaxrs - paramconverter ........... SUCCESS [ 4.300 s]
[INFO] Java EE 7 Sample: jaxrs - readerwriter ............. SUCCESS [ 4.483 s]
[INFO] Java EE 7 Sample: jaxrs - readerwriter-json ........ SUCCESS [ 0.204 s]
[INFO] Java EE 7 Sample: jaxrs - request-binding .......... SUCCESS [ 0.149 s]
[INFO] Java EE 7 Sample: jaxrs - resource-validation ...... FAILURE [ 4.474 s]
[INFO] Java EE 7 Sample: jaxrs - server-negotiation ....... FAILURE [ 4.112 s]
[INFO] Java EE 7 Sample: jaxrs - simple-get ............... SUCCESS [ 3.982 s]
[INFO] Java EE 7 Sample: jaxrs - singleton ................ SUCCESS [ 5.907 s]
[INFO] Java EE 7 Sample: jaxrs - readerwriter-injection ... FAILURE [ 2.542 s]
[INFO] Java EE 7 Sample: jaxrs - jaxrs-security-declarative SUCCESS [ 4.497 s]
[INFO] ------------------------------------------------------------------------
</pre>
</div>
<p>
<i>Arjan Tijms</i>Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-904479495127952019-11-29T04:16:00.001-08:002020-08-16T16:54:26.978-07:00The productive standupTimeboxing is a very simple technique to manage time and become more productive. Our OmniDevs have honed this technique to perfection!<br />
<p>
Here they are in their daily standup with scrum master Robert:<i>(click on the image for a larger version)</i>
</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgerAtuWs6oChoN0UFDJLpu5G4O8wzsmYUQEpDccXGAFTL-KeKoamxa0dZkiCwJDztg8Znyv6E-p3CQUScs7p7MFZz58yd2mxpkqiE_OCxjqvt_W_ADjEIzWixdGB_alGS5dQKr4DBLSr9K/s2048/omnidevs_comic2_large.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;">
<img border="0" data-original-height="1132" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgerAtuWs6oChoN0UFDJLpu5G4O8wzsmYUQEpDccXGAFTL-KeKoamxa0dZkiCwJDztg8Znyv6E-p3CQUScs7p7MFZz58yd2mxpkqiE_OCxjqvt_W_ADjEIzWixdGB_alGS5dQKr4DBLSr9K/s1600/omnidevs_comic2_large.jpg" width="800" />
</a>
</div>
<p>
Stay tuned for the next instalment!</p>
Previous strip: <a href="https://arjan-tijms.omnifaces.org/2019/11/estimations-are-easy.html">Estimations are easy!</a>
Next strip: <a href="https://arjan-tijms.omnifaces.org/2020/08/perfecting-business-structure.html">Perfecting the business structure</a>Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com3tag:blogger.com,1999:blog-4498889353428710313.post-33532485746115049152019-11-22T10:55:00.002-08:002020-08-16T17:09:19.191-07:00Estimations are easy!Now for something a little different on this blog, though still in the domain of development. Today we're introducing "The OmniDevs", a comic strip dedicated to our daily struggles as developers in this exciting, but at times crazy, place we call the software industry.
<p>
Without further ado, let's kick off with the first episode which is about the "favourite" pastime of most devs out there: estimating our work! <i>(click on the image for a larger version)</i>
</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkXq8Nic-jjhYS2Qzi_xkQ9kSua6kQxPErQGBD_-sTtcYTJMrLnW-RVpbXIk7Y1ZBqjjR2jXSmDg3U1G-DMVWu-L_X-q1a1f1SrFhyWX-rCzZ2SKlToQV9gP-F8J9xSIEi0sAMSVGgg4kf/s2048/omnidevs_comic1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;">
<img border="0" data-original-height="1135" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkXq8Nic-jjhYS2Qzi_xkQ9kSua6kQxPErQGBD_-sTtcYTJMrLnW-RVpbXIk7Y1ZBqjjR2jXSmDg3U1G-DMVWu-L_X-q1a1f1SrFhyWX-rCzZ2SKlToQV9gP-F8J9xSIEi0sAMSVGgg4kf/s1600/omnidevs_comic1.jpg" width="800" />
</a></div>
</p>
<p>
Stay tuned for the next instalment!
Next strip: <a href="https://arjan-tijms.omnifaces.org/2019/11/the-productive-standup.html">The productive standup</a>
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com2tag:blogger.com,1999:blog-4498889353428710313.post-54622567512973303812018-05-07T08:44:00.000-07:002018-05-07T14:47:16.966-07:00Java EE Survey 2018 - resultsAt OmniFaces we poll the community from <a href="http://arjan-tijms.omnifaces.org/2015/03/the-most-popular-java-ee-servers-in.html">time</a> to <a href="http://arjan-tijms.omnifaces.org/2017/06/should-community-take-over-jsfnext-or.html">time</a> about Java EE and related technologies. With all the changes that are about to happen with the move of <a href="https://github.com/javaee">Java EE</a> to <a href="https://github.com/eclipse-ee4j">Eclipse</a> and the subsequent <a href="http://www.tomitribe.com/blog/2018/02/java-ee-to-jakarta-ee/">renaming to Jakarta EE</a>, we expanded the survey a little for this year.
<p>
In the 2018 edition, there were 4 categories of questions:
<ul>
<li>Current usage of Java EE</li>
<li>Servlet containers</li>
<li>APIs related to Java EE</li>
<li>The future of Java EE / Jakarta EE</li>
</ul>
<p>
Jakarta EE provides the opportunity to revitalise and modernise Java EE, but in order to do that it's more important than ever that we know what matters to all of its users out there.
<p>
We started the survey the 15th of March, 2018. Unfortunately a small barrage of other surveys would soon follow, among others the <a href="https://jakarta.ee/news/2018/04/24/jakarta-ee-community-survey/">Eclipse Jakarta EE Survey</a>, the Jakarta EE Logo selection, and the <a href="http://baeldung.com/java-in-2018">Baeldung survey</a>. Despite all those other surveys going on at the same time we still managed to get <b>1054 respondents</b>. Not as much as we hoped for, but still enough to have some idea of what's important to the community.
<p>
It must be noted that OmniFaces is a JSF utility library, so the public we attract is naturally more interested in JSF than the primary public of the many parallel surveys that were going on. We did track where the respondents originated from, and <b>344</b> of them took the survey directly on the <a href="http://omnifaces.org">omnifaces.org</a> website.
<p>
It must also be disclosed that one of the OmniFaces members (the writer, Arjan), works for <a href="https://payara.fish">Payara</a>. Payara however was in no way involved with either the creation of the survey or the report. Payara did tweet about the survey a couple of times.
<p>
Let's take a look at the outcome now.
<p> </p>
<h2>Question 1 - Which versions of Java EE have you (historically) used?</h2>
<p>
This question was about which version of Java EE people have ever used, and hopefully will give us some idea of how much experience our audience has and how long they've been using Java EE.
<p>
It appears though that most of our respondents haven't used the older versions so much. Far less than half of the respondents has ever used Java EE 5. On the other hand, there's still a relatively big proportion of respondents that have used the precursor technologies of Java EE (the ones older than J2EE 1.2).
<p>
<svg version="1.2" width="159.86mm" height="89.96mm" viewBox="2616 10431 15986 8996" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xml:space="preserve">
<defs class="ClipPathGroup">
<clipPath id="presentation_clip_path" clipPathUnits="userSpaceOnUse">
<rect x="2616" y="10431" width="15986" height="8996"/>
</clipPath>
<clipPath id="presentation_clip_path_shrink" clipPathUnits="userSpaceOnUse">
<rect x="2631" y="10439" width="15955" height="8979"/>
</clipPath>
</defs>
<defs>
<font id="EmbeddedFont_1" horiz-adv-x="2048">
<font-face font-family="Helvetica Neue embedded" units-per-em="2048" font-weight="normal" font-style="normal" ascent="1952" descent="447"/>
<missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/>
<glyph unicode="v" horiz-adv-x="988" d="M 608,0 L 995,1059 813,1059 524,176 520,176 223,1059 29,1059 422,0 Z"/>
<glyph unicode="a" horiz-adv-x="1012" d="M 1069,4 C 1039,-14 997,-23 944,-23 899,-23 863,-10 837,15 810,41 797,82 797,139 749,82 693,41 630,15 566,-10 498,-23 424,-23 376,-23 331,-17 288,-6 245,5 208,22 176,45 145,68 120,99 101,136 83,174 74,219 74,272 74,332 84,382 104,420 125,458 152,489 185,513 219,537 257,555 300,567 343,580 387,590 432,598 480,608 525,615 568,620 611,624 649,631 682,640 715,649 741,662 760,679 779,696 788,721 788,754 788,792 781,823 767,846 753,869 734,887 712,899 689,911 664,920 636,924 608,928 580,930 553,930 479,930 418,916 369,888 319,860 293,807 289,729 L 115,729 C 117,795 131,850 156,895 180,940 213,977 254,1005 295,1033 342,1053 394,1065 447,1077 503,1083 563,1083 611,1083 658,1080 706,1073 753,1066 795,1052 834,1031 872,1010 902,980 926,942 949,904 961,854 961,793 L 961,248 C 961,207 963,177 968,158 972,139 989,129 1016,129 1031,129 1049,132 1069,139 Z M 786,547 C 765,530 736,518 700,511 665,503 628,497 589,493 550,488 511,482 471,476 431,470 396,460 365,446 333,433 308,413 288,388 268,363 258,328 258,285 258,256 264,232 275,212 287,192 302,176 321,164 339,152 360,143 385,137 410,132 436,129 463,129 520,129 569,137 610,153 651,168 685,188 711,212 737,236 756,262 768,290 780,318 786,344 786,369 Z"/>
<glyph unicode="J" horiz-adv-x="894" d="M 903,365 L 903,1462 709,1462 709,393 C 709,313 692,248 658,201 625,153 564,129 475,129 427,129 388,136 357,151 327,165 303,185 286,211 269,237 257,268 250,303 243,339 240,378 240,420 L 240,481 45,481 45,391 C 45,252 82,146 156,75 229,3 335,-33 471,-33 553,-33 622,-22 677,1 732,24 777,54 810,91 843,129 867,171 882,219 896,267 903,315 903,365 Z"/>
<glyph unicode="E" horiz-adv-x="1036" d="M 160,1462 L 160,0 1176,0 1176,164 354,164 354,670 1114,670 1114,834 354,834 354,1298 1169,1298 1169,1462 Z"/>
<glyph unicode="<" horiz-adv-x="1059" d="M 1135,913 L 1135,1053 94,582 94,455 1135,-14 1135,123 264,518 Z"/>
<glyph unicode="9" horiz-adv-x="1012" d="M 274,350 L 100,350 C 111,225 157,131 238,70 318,8 419,-23 541,-23 717,-23 845,45 925,179 1005,314 1044,507 1044,758 1044,896 1031,1009 1005,1099 978,1188 942,1259 897,1311 852,1363 799,1399 739,1420 679,1441 615,1452 547,1452 477,1452 413,1440 354,1417 296,1394 245,1362 203,1320 160,1278 128,1228 104,1170 81,1112 70,1049 70,979 70,908 80,842 99,782 119,722 148,671 187,629 226,586 274,553 332,529 389,506 455,494 528,494 599,494 665,512 725,548 785,584 831,633 864,694 L 868,690 C 863,500 834,359 780,267 727,175 647,129 541,129 471,129 411,148 360,186 310,225 281,279 274,350 Z M 838,967 C 838,924 831,884 817,845 803,806 784,772 758,742 732,713 700,690 664,673 627,656 586,647 541,647 498,647 460,656 425,673 390,690 360,713 335,741 310,770 290,803 275,840 261,877 254,915 254,954 254,999 259,1042 269,1083 280,1124 296,1161 318,1193 341,1225 370,1251 407,1270 443,1289 487,1298 539,1298 588,1298 631,1290 668,1272 705,1254 736,1230 761,1199 786,1168 805,1133 818,1094 831,1054 838,1012 838,967 Z"/>
<glyph unicode="8" horiz-adv-x="988" d="M 317,1075 C 317,1112 324,1144 338,1171 352,1199 370,1222 392,1241 415,1260 442,1275 473,1284 504,1294 537,1298 571,1298 642,1298 701,1280 746,1242 792,1205 815,1149 815,1075 815,1001 793,944 748,903 702,862 645,842 575,842 540,842 507,847 475,856 444,866 416,880 393,899 370,918 352,942 338,972 324,1001 317,1036 317,1075 Z M 133,1081 C 133,1016 152,955 188,900 225,845 274,805 336,780 254,752 191,706 147,642 104,579 82,504 82,418 82,344 95,280 120,224 145,169 180,123 224,86 269,49 321,22 381,4 441,-14 506,-23 575,-23 642,-23 705,-13 764,6 823,25 873,54 916,91 959,129 994,175 1019,229 1044,284 1057,347 1057,418 1057,508 1036,584 993,646 951,708 886,753 799,780 860,808 909,848 945,902 981,956 999,1016 999,1081 999,1128 991,1173 975,1218 958,1262 933,1302 898,1336 863,1371 818,1399 762,1420 706,1441 638,1452 559,1452 503,1452 450,1444 398,1427 347,1411 302,1387 262,1356 223,1324 191,1286 168,1240 145,1194 133,1141 133,1081 Z M 266,410 C 266,452 274,490 290,524 305,558 327,588 355,612 383,637 416,656 454,669 491,682 531,688 573,688 614,688 653,681 689,667 725,652 757,633 784,608 812,584 833,555 849,521 865,488 872,451 872,412 872,371 865,333 851,299 837,265 816,235 790,210 763,185 731,165 695,151 659,136 619,129 575,129 485,129 411,154 353,204 295,254 266,322 266,410 Z"/>
<glyph unicode="7" horiz-adv-x="965" d="M 1042,1278 L 1042,1427 102,1427 102,1264 864,1264 C 788,1183 716,1095 650,999 584,904 526,802 475,695 425,588 383,476 351,359 319,243 299,123 291,0 L 485,0 C 492,113 511,230 543,350 574,470 615,587 665,700 714,814 771,920 836,1020 900,1120 969,1206 1042,1278 Z"/>
<glyph unicode="6" horiz-adv-x="1012" d="M 848,1081 L 1022,1081 C 1011,1201 970,1293 899,1357 828,1420 733,1452 612,1452 509,1452 423,1430 354,1386 286,1343 231,1285 190,1212 150,1140 120,1057 103,964 86,870 78,773 78,674 78,597 84,518 95,436 107,354 130,279 166,211 201,143 252,87 317,43 383,-1 470,-23 578,-23 669,-23 746,-7 808,24 870,54 920,93 957,140 995,187 1022,240 1038,297 1055,354 1063,410 1063,463 1063,530 1053,592 1032,649 1012,707 983,756 945,799 908,841 861,874 806,898 751,922 688,934 618,934 539,934 469,919 409,889 348,859 297,810 256,743 L 252,748 C 253,803 259,864 268,928 278,992 295,1052 321,1107 346,1162 381,1208 426,1244 471,1280 530,1298 604,1298 674,1298 730,1279 772,1239 814,1199 840,1147 848,1081 Z M 586,780 C 635,780 678,771 715,754 752,736 782,712 807,683 831,654 850,619 861,579 873,538 879,496 879,451 879,408 872,368 859,329 846,290 827,255 803,225 778,195 748,172 712,155 675,138 634,129 586,129 538,129 495,138 458,155 420,172 389,195 364,223 338,252 319,286 305,326 291,365 285,408 285,453 285,498 291,540 304,581 317,621 337,656 362,685 388,714 420,738 457,755 494,772 537,780 586,780 Z"/>
<glyph unicode="5" horiz-adv-x="988" d="M 963,1274 L 963,1427 246,1427 111,674 260,666 C 294,707 333,740 378,765 422,790 473,803 530,803 580,803 624,795 665,778 705,762 739,739 768,710 797,680 819,645 835,605 850,565 858,521 858,473 858,416 850,366 834,323 817,280 795,244 767,215 739,186 706,165 669,151 631,136 592,129 551,129 507,129 467,136 431,148 395,161 364,180 337,204 310,228 289,256 273,288 258,320 248,354 246,391 L 72,391 C 73,326 86,267 111,215 135,163 169,120 211,85 253,50 302,24 357,5 413,-13 472,-23 535,-23 619,-23 693,-9 757,17 820,44 873,80 915,125 958,170 990,222 1011,280 1032,338 1042,397 1042,459 1042,542 1030,615 1006,677 981,739 948,791 905,833 863,874 813,905 756,926 698,946 638,956 573,956 524,956 475,948 425,931 375,914 335,887 303,852 L 299,856 377,1274 Z"/>
<glyph unicode="4" horiz-adv-x="1012" d="M 694,494 L 207,494 690,1204 694,1204 Z M 858,494 L 858,1452 719,1452 57,508 57,340 694,340 694,0 858,0 858,340 1055,340 1055,494 Z"/>
<glyph unicode="3" horiz-adv-x="1012" d="M 446,829 L 446,682 C 479,686 514,688 551,688 595,688 635,682 673,671 710,659 743,641 770,617 797,594 819,564 836,529 852,495 860,455 860,410 860,366 852,327 835,292 817,257 795,228 766,204 737,180 704,161 666,148 627,136 587,129 545,129 445,129 369,159 317,218 266,278 238,354 236,449 L 61,449 C 60,373 71,307 93,248 116,189 148,140 190,99 233,59 284,29 344,8 404,-12 471,-23 545,-23 613,-23 678,-13 738,5 799,24 852,51 897,88 942,125 978,171 1005,226 1031,282 1044,345 1044,418 1044,505 1023,581 980,645 937,709 871,751 782,770 L 782,774 C 840,800 887,838 926,889 964,939 983,997 983,1063 983,1130 972,1188 949,1237 927,1286 896,1326 856,1358 816,1389 770,1413 716,1428 662,1444 603,1452 541,1452 468,1452 404,1440 349,1417 294,1394 248,1362 211,1321 174,1280 146,1231 126,1174 106,1116 95,1053 92,983 L 266,983 C 266,1025 272,1066 283,1104 294,1142 310,1176 333,1204 355,1233 384,1256 419,1273 454,1290 494,1298 541,1298 614,1298 676,1279 725,1240 774,1201 799,1143 799,1065 799,1027 791,993 776,963 761,933 741,908 716,888 691,868 661,853 628,843 594,833 559,827 522,827 L 485,827 C 479,827 472,827 465,827 459,827 453,828 446,829 Z"/>
<glyph unicode="2" horiz-adv-x="989" d="M 90,938 L 264,938 C 263,982 267,1025 278,1068 288,1111 304,1150 328,1184 351,1218 381,1246 417,1267 453,1288 496,1298 547,1298 585,1298 621,1292 655,1280 689,1268 719,1250 744,1227 770,1204 790,1176 805,1144 820,1112 827,1076 827,1036 827,986 820,941 804,903 788,865 765,829 734,797 703,764 665,731 618,699 572,667 518,632 457,594 406,564 358,532 311,498 265,464 223,424 186,379 150,334 119,281 95,220 71,159 56,86 49,0 L 997,0 997,154 252,154 C 260,199 278,239 304,273 331,308 363,341 400,371 438,401 479,429 524,456 569,482 614,509 659,537 705,565 748,595 791,627 833,658 870,693 903,732 936,771 962,815 982,864 1002,913 1012,970 1012,1034 1012,1103 1000,1163 976,1214 952,1266 920,1310 879,1345 838,1379 790,1406 734,1424 679,1443 620,1452 557,1452 481,1452 412,1439 352,1413 292,1387 242,1351 202,1306 161,1260 132,1206 113,1143 94,1080 86,1012 90,938 Z"/>
<glyph unicode="1" horiz-adv-x="589" d="M 729,0 L 729,1452 596,1452 C 586,1397 569,1352 543,1317 517,1281 485,1253 447,1233 410,1212 368,1198 322,1191 275,1183 227,1180 178,1180 L 178,1040 555,1040 555,0 Z"/>
<glyph unicode="0" horiz-adv-x="988" d="M 270,715 C 270,750 271,790 271,833 272,876 275,919 282,962 288,1005 297,1047 308,1087 320,1128 337,1164 359,1195 382,1226 410,1251 444,1270 479,1289 520,1298 569,1298 618,1298 660,1289 694,1270 728,1251 757,1226 779,1195 802,1164 819,1128 830,1087 842,1047 851,1005 857,962 863,919 867,876 867,833 868,790 868,750 868,715 868,660 867,599 863,531 860,464 849,400 830,341 812,282 782,231 741,190 700,150 643,129 569,129 496,129 438,150 397,190 356,231 327,282 308,341 290,400 279,464 275,531 272,599 270,660 270,715 Z M 86,713 C 86,659 87,604 90,547 93,489 100,433 111,379 122,324 137,273 158,224 178,176 206,133 242,96 277,59 322,30 376,9 430,-12 494,-23 569,-23 646,-23 711,-12 764,9 817,30 862,59 897,96 933,133 961,176 981,224 1001,273 1017,324 1028,379 1039,433 1046,489 1049,547 1051,604 1053,659 1053,713 1053,766 1051,821 1049,879 1046,936 1039,992 1028,1047 1017,1101 1001,1153 981,1202 961,1251 933,1294 897,1331 862,1368 817,1397 763,1419 709,1441 644,1452 569,1452 494,1452 430,1441 376,1419 322,1397 277,1368 242,1331 206,1294 178,1251 158,1202 137,1153 122,1101 111,1047 100,992 93,936 90,879 87,821 86,766 86,713 Z"/>
<glyph unicode="." horiz-adv-x="236" d="M 170,227 L 170,0 397,0 397,227 Z"/>
<glyph unicode="%" horiz-adv-x="1694" d="M 342,1040 C 342,1072 344,1105 348,1140 352,1175 361,1207 374,1236 387,1265 405,1290 428,1310 451,1329 482,1339 520,1339 560,1339 591,1329 613,1310 636,1290 653,1265 666,1236 678,1207 686,1175 689,1140 693,1105 694,1072 694,1042 694,1011 692,978 688,942 684,907 675,874 663,845 650,815 631,791 608,772 585,753 554,743 514,743 476,743 445,753 423,773 400,793 383,817 371,847 358,876 351,908 347,943 344,978 342,1010 342,1040 Z M 188,1036 C 188,980 194,928 206,879 217,829 236,786 262,750 288,713 322,684 365,663 407,641 459,631 520,631 580,631 631,642 672,666 713,689 746,719 773,757 800,794 819,838 830,888 842,938 848,989 848,1042 848,1098 843,1151 833,1201 822,1251 805,1294 779,1331 754,1368 721,1397 679,1419 637,1441 584,1452 520,1452 457,1452 405,1441 362,1418 320,1396 286,1365 260,1327 234,1289 216,1245 205,1195 194,1145 188,1092 188,1036 Z M 1354,385 C 1354,416 1356,450 1360,484 1364,519 1373,551 1385,581 1398,610 1417,635 1440,654 1463,674 1494,684 1532,684 1571,684 1603,674 1625,654 1648,635 1665,610 1677,581 1690,551 1697,519 1701,484 1704,450 1706,417 1706,387 1706,356 1704,322 1700,287 1696,251 1687,219 1674,189 1661,160 1643,136 1620,117 1597,98 1565,88 1526,88 1488,88 1457,98 1435,118 1412,138 1395,162 1382,191 1370,221 1362,253 1359,288 1355,323 1354,355 1354,385 Z M 1200,381 C 1200,325 1206,272 1218,223 1229,174 1248,131 1274,95 1300,59 1334,30 1376,9 1419,-12 1470,-23 1532,-23 1592,-23 1642,-11 1683,11 1724,34 1758,64 1785,101 1811,139 1831,183 1842,232 1854,282 1860,334 1860,387 1860,443 1854,496 1844,546 1834,596 1816,639 1791,676 1766,713 1732,742 1691,764 1649,786 1596,797 1532,797 1469,797 1417,785 1374,763 1332,740 1298,710 1272,672 1246,634 1227,589 1217,540 1206,490 1200,437 1200,381 Z M 1487,1479 L 385,-43 561,-43 1661,1479 Z"/>
<glyph unicode=" " horiz-adv-x="564"/>
</font>
</defs>
<defs class="TextShapeIndex">
<g ooo:slide="id1" ooo:id-list="id3"/>
</defs>
<defs class="EmbeddedBulletChars">
<g id="bullet-char-template-57356" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z"/>
</g>
<g id="bullet-char-template-57354" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z"/>
</g>
<g id="bullet-char-template-10146" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z"/>
</g>
<g id="bullet-char-template-10132" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z"/>
</g>
<g id="bullet-char-template-10007" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z"/>
</g>
<g id="bullet-char-template-10004" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z"/>
</g>
<g id="bullet-char-template-9679" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z"/>
</g>
<g id="bullet-char-template-8226" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z"/>
</g>
<g id="bullet-char-template-8211" transform="scale(0.00048828125,-0.00048828125)">
<path d="M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z"/>
</g>
<g id="bullet-char-template-61548" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 173,740 C 173,903 231,1043 346,1159 462,1274 601,1332 765,1332 928,1332 1067,1274 1183,1159 1299,1043 1357,903 1357,740 1357,577 1299,437 1183,322 1067,206 928,148 765,148 601,148 462,206 346,322 231,437 173,577 173,740 Z"/>
</g>
</defs>
<defs class="TextEmbeddedBitmaps"/>
<g class="SlideGroup">
<g>
<g id="container-id1">
<g id="id1" class="Slide" clip-path="url(#presentation_clip_path)">
<g class="Page">
<g class="OLE2">
<g id="id3">
<rect class="BoundingBox" stroke="none" fill="none" x="2616" y="10431" width="15987" height="8997"/>
<defs>
<clipPath id="clip_path_1" clipPathUnits="userSpaceOnUse">
<path d="M 2611,10442 L 18603,10442 18603,19426 2611,19426 2611,10442 Z"/>
</clipPath>
</defs>
<g clip-path="url(#clip_path_1)"/>
<defs>
<clipPath id="clip_path_2" clipPathUnits="userSpaceOnUse">
<path d="M 2611,10442 L 18603,10442 18603,19426 2611,19426 2611,10442 Z"/>
</clipPath>
</defs>
<g clip-path="url(#clip_path_2)">
<path fill="rgb(255,255,255)" stroke="none" d="M 10610,19428 L 2616,19428 2616,10431 18603,10431 18603,19428 10610,19428 Z"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 11369,18575 L 4785,18575 4785,10610 17953,10610 17953,18575 11369,18575 Z"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4785,10609 L 4785,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 6248,10609 L 6248,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 7711,10609 L 7711,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 9174,10609 L 9174,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 10637,10609 L 10637,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 12100,10609 L 12100,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 13563,10609 L 13563,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 15026,10609 L 15026,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 16489,10609 L 16489,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 17953,10609 L 17953,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,18574 L 4785,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,18574 L 4785,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,17578 L 4785,17578"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,17578 L 4785,17578"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,16582 L 4785,16582"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,16582 L 4785,16582"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,15587 L 4785,15587"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,15587 L 4785,15587"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,14591 L 4785,14591"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,14591 L 4785,14591"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,13595 L 4785,13595"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,13595 L 4785,13595"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,12600 L 4785,12600"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,12600 L 4785,12600"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,11604 L 4785,11604"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,11604 L 4785,11604"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,10609 L 4785,10609"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4635,10609 L 4785,10609"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4785,18574 L 4785,10609"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4785,18724 L 4785,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4785,18724 L 4785,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 6248,18724 L 6248,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 6248,18724 L 6248,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 7711,18724 L 7711,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 7711,18724 L 7711,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 9174,18724 L 9174,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 9174,18724 L 9174,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 10637,18724 L 10637,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 10637,18724 L 10637,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 12100,18724 L 12100,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 12100,18724 L 12100,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 13563,18724 L 13563,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 13563,18724 L 13563,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 15026,18724 L 15026,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 15026,18724 L 15026,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 16489,18724 L 16489,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 16489,18724 L 16489,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 17953,18724 L 17953,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 17953,18724 L 17953,18574"/>
<path fill="none" stroke="rgb(179,179,179)" d="M 4785,18574 L 17953,18574"/>
<g>
<defs>
<linearGradient id="gradient1" x1="6560" y1="9832" x2="8032" y2="12380" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(114,159,207)"/>
<stop offset="1" style="stop-color:rgb(32,74,135)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient1)" d="M 4785,11355 L 4785,10857 9807,10857 9807,11355 4785,11355 Z"/>
</g>
<g>
<defs>
<linearGradient id="gradient2" x1="9102" y1="9360" x2="12268" y2="14844" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(114,159,207)"/>
<stop offset="1" style="stop-color:rgb(32,74,135)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient2)" d="M 4785,12351 L 4785,11853 16586,11853 16586,12351 4785,12351 Z"/>
</g>
<g>
<defs>
<linearGradient id="gradient3" x1="8110" y1="10929" x2="10614" y2="15266" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(114,159,207)"/>
<stop offset="1" style="stop-color:rgb(32,74,135)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient3)" d="M 4785,13346 L 4785,12849 13939,12849 13939,13346 4785,13346 Z"/>
</g>
<g>
<defs>
<linearGradient id="gradient4" x1="6757" y1="12706" x2="8359" y2="15480" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(114,159,207)"/>
<stop offset="1" style="stop-color:rgb(32,74,135)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient4)" d="M 4785,14342 L 4785,13844 10331,13844 10331,14342 4785,14342 Z"/>
</g>
<g>
<defs>
<linearGradient id="gradient5" x1="5949" y1="14167" x2="7015" y2="16011" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(114,159,207)"/>
<stop offset="1" style="stop-color:rgb(32,74,135)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient5)" d="M 4785,15338 L 4785,14840 8180,14840 8180,15338 4785,15338 Z"/>
</g>
<g>
<defs>
<linearGradient id="gradient6" x1="5330" y1="15521" x2="5981" y2="16648" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(114,159,207)"/>
<stop offset="1" style="stop-color:rgb(32,74,135)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient6)" d="M 4785,16333 L 4785,15836 6526,15836 6526,16333 4785,16333 Z"/>
</g>
<g>
<defs>
<linearGradient id="gradient7" x1="5238" y1="16568" x2="5830" y2="17592" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(114,159,207)"/>
<stop offset="1" style="stop-color:rgb(32,74,135)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient7)" d="M 4785,17329 L 4785,16831 6284,16831 6284,17329 4785,17329 Z"/>
</g>
<g>
<defs>
<linearGradient id="gradient8" x1="4952" y1="17730" x2="5352" y2="18422" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(114,159,207)"/>
<stop offset="1" style="stop-color:rgb(32,74,135)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient8)" d="M 4785,18325 L 4785,17827 5520,17827 5520,18325 4785,18325 Z"/>
</g>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="2936" y="18218"><tspan fill="rgb(0,0,0)" stroke="none">< J2EE 1.2</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="3241" y="17222"><tspan fill="rgb(0,0,0)" stroke="none">J2EE 1.2</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="3241" y="16226"><tspan fill="rgb(0,0,0)" stroke="none">J2EE 1.3</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="3241" y="15231"><tspan fill="rgb(0,0,0)" stroke="none">J2EE 1.4</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="3077" y="14235"><tspan fill="rgb(0,0,0)" stroke="none">Java EE 5</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="3077" y="13240"><tspan fill="rgb(0,0,0)" stroke="none">Java EE 6</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="3077" y="12244"><tspan fill="rgb(0,0,0)" stroke="none">Java EE 7</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="3077" y="11248"><tspan fill="rgb(0,0,0)" stroke="none">Java EE 8</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="4551" y="19177"><tspan fill="rgb(0,0,0)" stroke="none">0%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="5919" y="19177"><tspan fill="rgb(0,0,0)" stroke="none">10%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="7382" y="19177"><tspan fill="rgb(0,0,0)" stroke="none">20%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="8845" y="19177"><tspan fill="rgb(0,0,0)" stroke="none">30%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="10308" y="19177"><tspan fill="rgb(0,0,0)" stroke="none">40%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="11771" y="19177"><tspan fill="rgb(0,0,0)" stroke="none">50%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="13234" y="19177"><tspan fill="rgb(0,0,0)" stroke="none">60%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="14697" y="19177"><tspan fill="rgb(0,0,0)" stroke="none">70%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="16160" y="19177"><tspan fill="rgb(0,0,0)" stroke="none">80%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="17624" y="19177"><tspan fill="rgb(0,0,0)" stroke="none">90%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="5620" y="18218"><tspan fill="rgb(0,0,0)" stroke="none">5%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="6384" y="17222"><tspan fill="rgb(0,0,0)" stroke="none">10%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="6626" y="16226"><tspan fill="rgb(0,0,0)" stroke="none">12%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="8280" y="15231"><tspan fill="rgb(0,0,0)" stroke="none">23%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="10431" y="14235"><tspan fill="rgb(0,0,0)" stroke="none">38%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="14039" y="13240"><tspan fill="rgb(0,0,0)" stroke="none">63%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="16686" y="12244"><tspan fill="rgb(0,0,0)" stroke="none">81%</tspan></tspan></tspan></text>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica Neue" font-size="353px" font-weight="200"><tspan class="TextPosition" x="9907" y="11248"><tspan fill="rgb(0,0,0)" stroke="none">34%</tspan></tspan></tspan></text>
</g>
<g clip-path="url(#clip_path_1)"/>
<defs>
<clipPath id="clip_path_3" clipPathUnits="userSpaceOnUse">
<path d="M 2611,10442 L 18603,10442 18603,19426 2611,19426 2611,10442 Z"/>
</clipPath>
</defs>
<g clip-path="url(#clip_path_3)"/>
<g clip-path="url(#clip_path_1)"/>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
<p> </p>
<h2>Question 2 - Which versions of Java EE have you recently (last couple of months) used?</h2>
<p>
Looking at what people have recently been working on we see that J2EE 1.3 and J2EE 1.4 is almost non-existent. The response for those is well within the error margin. There's still a number of people working on Java EE 5 applications though, which is now more than a decade old! Not surprisingly, most people are working with Java EE 7, for which all currently active vendors have a supported version out.
<p>
Maybe somewhat surprisingly is that 36% of the respondents are already using Java EE 8, given that not all vendors have a fully supported version out or have even implemented all Java EE 8 APIs yet. Of course, this can also mean respondents are using parts of Java EE 8. <a href="http://wildfly.org/news/2018/02/28/WildFly12-Final-Released">WildFly 12</a> for instance supports most Java EE 8 APIs, except for EE Security (which will come in WildFly 13).
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/2.svg">
<p> </p>
<h2>Question 3 - Which application servers have you recently used?</h2>
<p>
Looking at which (Java EE) application servers are most frequently used there's a very clear winner, and that's RedHat's <a href="http://wildfly.org">WildFly</a>. More than half of the respondents have recently used this server. Trailing a good deal behind at the second place is Oracle's GlassFish. Despite being largely abandoned by Oracle and <a href="https://www.theregister.co.uk/2013/11/05/no_commercial_support_for_glassfish_4/">not supported</a>, still 37% of responds use this. <a href="https://payara.fish">Payara Server</a> and <a href="http://tomee.apache.org">TomEE</a> share the third place.
<p>
A slew of servers had so few respondents that taking the error margin into account qualifies them as practically unused by our respondents. This included <a href="http://geronimo.apache.org">Geronimo</a>, the <a href="https://www.javaworld.com/article/2077800/open-source-tools/jboss--geronimo--or-tomcat-.html">once promising server</a> from Apache that silently and without any notice stopped, <a href="http://caucho.com/products/resin">Resin</a>, a very promising Web Profile implementation back then with its own CDI implementation (CanDI), which however never managed to get passed Java EE 6, and <a href="https://jonas.ow2.org">JOnAS</a>, the mostly French server which had a number of its own unique component implementations as well, but like Geronimo just silently stopped at some point. Following is a number of mostly Korean, Japanese and Chinese servers. These servers are mostly used in their respective countries, and seemingly English language surveys are not (much) picked up by the users of these servers.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/3.svg">
<p> </p>
<h2>Question 4 - How would you rate the application servers that you've used?</h2>
<p>
For this question respondents could rate the servers they've used using 5 categories. There were two negative ones: "Hate it" and "Don't like it", a neutral one: "It does the job, but that's all", and two positive ones "Like it" and "Love it". The outcome has different aspects that we'll be looking at individually. Note that the servers that weren't effectively used by anyone are left out.
<h3>Love it</h3>
<p>
The first aspect we'll be looking at is a ranking of all servers that got the maximum appreciation: "Love it". Here we see <a href="https://payara.fish">Payara Server</a> is the winner. Almost half of the people who used Payara said they loved it. At the second place we see <a href="http://wildfly.org">WildFly</a> again, where over a third of the respondents who use WildFly said they loved it. Do note that since WildFly is used much more than Payara Server, in absolute numbers more respondents from this survey loved WildFly. Statistics can be a tricky thing.
<p>
Quite interesting is that <a href="https://developer.ibm.com/wasdev/websphere-liberty/">Liberty</a> is relatively much loved and enters at the third place. Liberty is IBM's still relatively new server that <a href="https://arjan-tijms.omnifaces.org/2013/06/trying-liberty-855.html">does many things right</a> compared to its older sibling WebSphere. Also interesting to see is the stark difference in love between Payara Server and GlassFish. Payara Server is directly based on GlassFish, but with many extra bug fixes and features.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/4-love.svg">
<h3>Like it</h3>
<p>
In the "Like it" category we see WildFly and JBoss EAP topping the chart. Note that these too are largely the same server, with JBoss EAP essentially a kind of "<a href="https://en.wikipedia.org/wiki/Long-term_support">LTS</a>" of a specific WildFly version with the option to get a support subscription and extra bug fixes. With the exception of <a href="http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-main-097127.html">WebLogic</a> and WebSphere, the servers are quite close together in this category.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/4-like.svg">
<h3>Hate it</h3>
<p>
Skipping the neutral and dislike categories (they'll be included in the final score though), let's take a look at the hate category. Overal we see that there's relatively little hate among the respondents. Liberty, JBoss EAP, TomEE, GlassFish, Payara Server and WildFly all have very small percentages of hate. The only real exception is WebSphere here, and to a lesser degree WebLogic. In the case of WebSphere, it's perhaps not a surprise. Only its installer is already larger than many complete servers (around the 100MB), and it downloads in excess of 2GB of "stuff". Even in 2018 that's still excessive. After that an actual server needs to be created taking another 200MB or so. This and a number of other issues (e.g. not being able to run on macOS) doesn't make it much popular. Of course IBM recognised this long ago, and all new development is on Liberty, which is essentially everything that WebSphere is not.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/4-hate.svg">
<h3>Total score</h3>
<p>
For the total score we used a weighted sum, with the weights (factors) being <i>-3</i> for "Hate it", <i>-2</i> for "Don't like it", <i>1</i> for "It does the job, but that's all", <i>2</i> for "Like it" and <i>3</i> for "Love it". For this total score we see Payara Server still wins, but now it's only a small margin with WildFly, which is very close. This seems mainly attributed to WildFly having many more points in the "Like it" category. In the next group we see Liberty, TomEE, JBoss EAP and GlassFish all scoring quite close to each other. All the way at bottom we find WebLogic and WebSphere. WebLogic just about manages to get a positive score, but WebSphere's is deeply negative.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/4-total.svg">
<p> </p>
<h2>Question 5 - Which Java EE APIs have you used recently?</h2>
<p>
When looking at the Java EE APIs that people use most, <a href="https://en.wikipedia.org/wiki/Java_Persistence_API">JPA</a> is the overal winner. This is interesting, since in recent years efforts for the JPA spec have been minimised, even to the point that one not rarely hears that JPA is "done" and people have moved on to e.g. MongoDB. Looking at the outcome of this survey this doesn't seem to be exactly the case. <a href="http://cdi-spec.org">CDI</a> follows close and lands at the second place. This is probably no surprise, as since its inception in 2009 CDI has rapidly increased in performance and is now for many cases the default type of bean to use.
<p>
Initially somewhat surprising is JSF scoring so high here, and landing just above <a href="https://en.wikipedia.org/wiki/Java_API_for_RESTful_Web_Services">JAX-RS</a> at the 3rd place. This is surprising since there's a quite vocal community out there proclaiming the era of server side rendering frameworks has come to an end, and the future belongs to the client. For obvious reasons we at OmniFaces don't fully agree with that, but we're also not entirely blind to the fact that the client has indeed taken a large bite out of the total web framework market. As mentioned in the beginning of this article, OmniFaces is a JSF utility library, so our audience likely has a more than average amount of JSF users among it.
<p>
Truly surprising though is the high score of EJB, which is often cited as having its name tainted by the complexities of EJB 2 and never quite recovered. Even though EJB 3 is very usable, in Java EE 7 and above CDI can be used instead for quite a lot of cases. It could of course be that EJB is only used for a few small things such as its timer service, but this would need more research and possibly a follow-up survey to really get clear.
<p>
<a href="https://www.ibm.com/developerworks/library/j-javaee8-security-api-1/index.html">Java EE Security</a>, a new spec in Java EE 8, is already used by 24% of the respondents. Given its young age this is quite a good outcome. <a href="https://dzone.com/articles/using-jaspic-secure-web">JASPIC</a> and JACC are both at the very bottom, but these APIs (SPIs actually) are not really aimed at application developers. They are used by higher level frameworks and vendors, e.g. the Java EE Security API strongly builds on JASPIC and will likely build more on JACC in a future release. So these APIs are being used, but just not directly by application developers. A somewhat similar thing also holds for JTA, which is mostly used under the covers by JPA and EJB, but is effectively used directly with the relatively new @Transactional and <a href="http://www.byteslounge.com/tutorials/java-ee-cdi-transactionscoped-example">@TransactionScoped</a> annotations.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/5.svg">
<p> </p>
<h2>Question 6 - Have you used a (standalone) Servlet container recently?</h2>
<p>
A standalone Servlet container is a server that supports at least the Servlet spec, and typically a number of strongly related specs such as the Servlet Container Profile of JASPIC (not full JASPIC), Expression Language, JNDI, JSP and WebSocket.
<p>
As it appears, about the half of the respondents have used such Servlet container, while the other half hasn't (and thus only used a full or web profile Java EE server).
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/6.svg">
<p> </p>
<h2>Question 7 - Which Servlet containers have you used recently?</h2>
<p>
From the people who have used a Servlet container, the overwhelming majority used at least Tomcat. At 85% Tomcat largely dominates this segment. Still, 29% and 22% for Jetty and Undertow are nothing to sneeze at either, and seemingly a non-trivial amount of respondents use either Jetty or Undertow next to Tomcat (people could choose multiple servers).
<p>
Undertow's 22% is particularly impressive, as Undertow is not so much known as a standalone Servlet container but more as the Servlet container that Jboss EAP/WildFly uses. It's also relatively new, especially when compared to Tomcat and Jetty which both have existed since the dawn of times.
<p>
The "other" category was perhaps not entirely understood, as most respondents choosing this entered products that actually weren't standalone Servlet containers. WebLogic, GlassFish, Liberty and Payara certainly aren't. Grizzly and Netty come closer, but they actually are more akin to HTTP engines, and are themselves not Servlet compatible.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/7.svg">
<h3>Other</h3>
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/7-tag.svg" width="80%" height="80%">
<p> </p>
<h2>Question 8 - Which additional Java EE libraries do you use with your Servlet container?</h2>
<p>
This question asked specifically about the <b>Java EE</b> libraries that people add to their Servlet containers. Java EE libraries here means an implementation of a Java EE spec, such as JPA and CDI, but not e.g. Guave, Spring, etc.
<p>
Consistent with the API usage outcome, JPA is added most often to a standalone Servlet container, followed by JSF, JAX-RS, Bean Validation and CDI. In this particular question though it was asked which exact implementation people add. As can be seen Hibernate wins hands down over EclipseLink (25%) and OpenJPA (7%). Likewise Mojarra (46%) wins over MyFaces (15%) and Jersey (45%) wins over RESTEasy (28%) and CFX (17%).
<p>
The EE Security API has only one standalone implementation yet, which is Soteria (there's another implementation by IBM, but it's embedded in Liberty and not suitable for standalone use). This one is quite new and only used by a couple of people, but it's nevertheless interesting that it is being used standalone.
<p>
The "Other" category wasn't entirely understood however. The idea was for other implementations of Java EE specs to be listed here, like e.g. Wink for JAX-RS, HornetQ, OpenMQ or JORAM for JMS, Narayana or JOTM for JTA, etc. None of these were mentioned though, and instead PrimeFaces, OmniFaces, DeltaSpike and Spring were mentioned, which aren't implementations of Java EE specs. Here it's probably the wording of the survey question that's to blame. One respondent did mention <a href="http://datanucleus.org">DataNucleus</a> though, which is a JPA implementation, and suggested that the question is biased against it by not mentioning it. Given the importance of JPA this is indeed true, so we'll make sure to include DataNucleus next year.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/8.svg">
<h3>Other</h3>
<p>
<img src="https://rawgit.com/arjantijms/javaee2018-report/master/8-tag.svg" width="80%" height="80%">
<p> </p>
<h2>Question 9 - Have you used MicroProfile APIs recently?</h2>
<p>
<a href="https://microprofile.io">MicroProfile</a> is an industry effort to bring extra APIs into the EE fold for things which Java EE doesn't have an API now, such as configuration and metrics. At the same time MicroProfile is also a profile like WebProfile, where only those extra APIs are included as well as JAX-RS and CDI.
<p>
Despite all Java EE vendors, with the exception of Oracle, offering those extra APIs with their products, and some implementations being able to be used standalone as well, usage among the respondents was quite low. Only a little more over 15% said to have used MicroProfile APIs recently.
<p>
This may have to do with all of those APIs being still very young and haven't established themselves yet. Another reason could be that most vendors by default promote MicroProfile as its own isolated product and not as an extra set of APIs to be used together with the main Java EE ones (Payara is the only notable exception here). As most people would use for example the regular WildFly server (as opposed to the spin-off product <a href="http://wildfly-swarm.io">WildFly Swarm</a>), which doesn't have the MicroProfile APIs out of the box, this could be a potential barrier.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/9.svg">
<p> </p>
<h2>Question 10 - Which MicroProfile products have you used recently?</h2>
<p>
Looking at which server product those relatively few people that use MicroProfile APIs use it's again WildFly that tops the charts here, with more than 50% of respondents using this variation of the WildFly main server. <a href="https://payara.fish/payara_micro">Payara Micro</a> follows closely with 45%. Compared to the (Java EE) server product the gap between WildFly and Payara is much smaller here. Payara also has all the MicroProfile APIs included out of the box with the EE Server product, and in this variation Liberty and Payara are used exactly as much. There are various other MicroProfile products, but they are not (yet) so popular (specifically when taking into account only a small proportion of respondents said to be using MicroProfile in the first place)
<p>
Seeing that <a href="https://payara.fish/payara_micro">Payara Micro</a> is more used for MicroProfile APIs than Payara Server, one may come to the conclusion that the fact that most MicroProfile vendors don't support these APIs out of the box on their server product doesn't matter that much. While this may be true, it could also be that many users aren't quite aware Payara Server supports these APIs.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/10.svg">
<p> </p>
<h2>Question 11 - Which MicroProfile APIs have you used recently?</h2>
<p>
<a href="https://www.ibm.com/support/knowledgecenter/en/SSAW57_liberty/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/cwlp_microprofile_overview.html">Config</a> was the first MicroProfile API and arguably one of the APIs that's most missed in Java EE. A Java EE Configuration API was in the works, but it never materialised. It's perhaps no surprise that config is thus the most used API from the MicroProfile. Health, Metrics and JWT Authentication follow with some distance. Open API, Open Tracing and the Type-safe rest client are all quite new and haven't been implemented by all vendors yet, so it's not a big surprise these aren't used that much yet.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/11.svg">
<p> </p>
<h2>Question 12 - Which Java EE specific extension libraries have you used recently?</h2>
<p>
This question was specifically about Java EE extension libraries, meaning libraries that one can only use with Java EE. This mostly means libraries that extend or are plug-ins for JSF, CDI, JCA, etc. <a href="https://primefaces.org">PrimeFaces</a> is the clear winner here, followed with some distance by OmniFaces (but keep the bias in account, since the survey was promoted via the OmniFaces account and website). Given the popularity that Seam once had, and DeltaSpike being its spiritual successor, just over 20% feels a bit on the low side. DeltaSpike is certainly worth <a href="https://deltaspike.apache.org">looking at</a> though. Once one of the most frequently used JSF component libraries, RichFaces after being sunset by Red Hat has been reduced to only 13% usage, while newcomer BootsFaces has climbed up to that same percentage.
<p>
As far as the "Other" response goes, "<a href="https://myfaces.apache.org">MyFaces</a>" was mentioned a lot, but this of course isn't a Java EE Extension library, but a Java EE Implementation library (it implements JSF, as mentioned in a previous question). Tobago, ButterFaces, IceFaces and PrettyFaces are indeed all Java EE extension libraries. Oracle ADF is too, although this is a somewhat specific one (it practically only really works on WebLogic). It's a question if one can really count Spring as a Java EE extension framework. Technically it is, but at the same time it mostly positions itself as an independent full stack framework.
<p>
So again, for next year we could do with an explicit definition of "Java EE specific extension library".
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/12.svg">
<h3>Other</h3>
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/12-other.svg">
<p> </p>
<h2>Question 13 - Which APIs would you most like to see updated in the next version of Java EE (Jakarta EE)?</h2>
<p>
When asked which API (spec) people like to see updated, a natural instinct might be to say "all of them". Perhaps not including the ones they hate, or maybe even those so that they can be hated a little less. With only a finite amount of resources this is not always an option, so that's why this question specifically asks respondents to rank the available APIs.
<p>
We take a look at the results in three different ways; the amount of people who put an API on the number one position, the amount of people who put an API on the number two position, and finally the total weighted score per API.
<h3>APIs at number 1 of the ranking</h3>
<p>
As can be seen none of the APIs had a really absolute majority. The highest score here was JSF with just over 20%. The question is, did JSF score so (relatively) high here because the potential bias, or do many people see JSF as something that has potential but *really* could do with some desperately needed improvements? CDI and JPA are high on this list too, which matches the outcome of which APIs people use most. Java EE Security is somewhat of an outlier. Being a new spec in Java EE 8 it isn't used that much yet, but already people want to see it improved. As a side-note, Java EE Security 1.0 could only address some of the basics (the low hanging fruit). More was planned for 1.0, but a lack of resources prevented many of those other planned things (such as security interceptors, evens and custom authorization rules) to be actually included.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/13-1.svg">
<h3>APIs at number 2 of the ranking</h3>
<p>
In the number 2 list we see some more variety in the category of APIs having more than 2% of the respondents choosing them, although we do largely see the same APIs again in the top tier. CDI now takes the lead, moving up one place from the number 1 list, and JAX-RS moves up 3 places. JPA is again at number 3, while JSF is at 4 now.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/13-2.svg">
<h3>Total score</h3>
<p>
When we take a look at the total score, we see that the top tier is formed of JPA, CDI and JAX-RS, which is basically identical to the top tier of question 5, which asked what APIs people have used recently. Clearly, people like to see APIs that they actually use improve. In the total score ranking too, EE Security is the exception. It lands on the 4th place, just an inch away from JAX-RS. Interestingly though, JASPIC and JACC end at the last places. As mentioned above, it's likely not common knowledge that these two APIs are the foundation of EE Security.
<p>
JavaMail and JDNI are both two examples of APIs that are used more than that people want to have them improved. Likely they just do the job (sending mails resp. looking up resources) and people don't see much need for further improvements there.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/13-tot.svg">
<p> </p>
<h2>Question 14 - What do you think about these options to improve Java EE / Jakarta EE?</h2>
<p>
This question asked for a variety of broad, somewhat cross-cutting concerns to improve Java EE overall (the potentially improved Java EE will be called Jakarta EE then). The choices with their keys in the graph were:
<ul>
<li> <b>CDI rebase</b> - Rebase most Java EE APIs on CDI (remove JSF @ManagedBeans, remove JAX-RS @Context, ...)
<li> <b>Remove deprecated</b> - Aggressively remove everything that is already @Deprecated (e.g. getServlet() in ServletContext)
<li> <b>Deprecate legacy</b> - Aggressively deprecate and remove legacy features (e.g. JSP support in JSF)
<li> <b>Add MP APIs</b> - Add equivalents of some or all MicroProfile APIs to Java EE (e.g. Config, JWT, ...)
<li> <b>Deployment models</b> - Officially add alternative deployment models (Uberjar, run .war from command line, etc)
<li> <b>Add JCache</b> - Add JCache to Java EE so that both applications and internal components (such as JPA) can use it
<li> <b>Rebase on Concurrency</b> - Rebase most Java EE APIs that use threading to use Concurrency Utils thread pools
<li> <b>Cloud connectors</b> - Add more connectors to cloud services (e.g. Amazon SQS, MQTT, Apache Kafka)
<li> <b>Security connectors</b> - Add more connectors to security services (e.g. OAuth2, SAML, OpenID, Yubikey)
</ul>
<p>
We'll be looking at two graphs for this one; the one which shows the options for which respondents choose "Please do this!", and the one with the weighted outcome (using the same weights as in question 4).
<h3>Please do this!</h3>
<p>
Of all the options presented, rebasing most Java EE APIs on CDI is the one that most people really want to see. It's followed closely by more security connectors (authentication mechanisms). Clearly the ones that currently ship by default with Java EE, namely FORM (+ custom form), BASIC, DIGEST and CERT aren't enough anymore. MicroProfile recognised this too and therefor added a <a href="https://github.com/eclipse/microprofile-jwt-auth">JWT authentication mechanism</a> as one of the initial new APIs.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/14-1.svg">
<h3>Weighted score</h3>
<p>
When looking at the weighted score, we see that all options presented have community support. Security connectors though have the most support, followed with some distance by adding JCache. Rebasing on CDI and Concurrency Utils, which could indirectly be taken as a wish to have a better integrated platform, has much support as well. At the bottom of the graph we see "Remove deprecated" and "Deprecate legacy". Seemingly people support removing some of the cruft that's in Java EE, but they are not overly concerned about this.
<p>
It's interesting to see that the alternative "Deployment models", which according to some vocal voices is *the* reason Java EE has been losing ground (the AS model is allegedly outdated), doesn't bother our respondents that much either. A reason is perhaps that with popular tools such as docker it doesn't matter so much whether you put an AS in it, or an uberjar. The AS might be known outside Java EE as a super large monolith, but actual Java EE users probably know that a modern AS is ~70 to 100mb and starts between 1 and about 3 seconds, while an uberjar can easily be around that same size too and starts in about the same time as well.
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/14-tot.svg">
<p> </p>
<h2>Question 15 - Do you have any final comments on how Java EE / Jakarta EE can be improved in the future?</h2>
<p>
The final question was a fully open question where people could comment whatever they wanted. 179 respondents left a comment, which is about 16% of the total number of respondents. Overal the quality of the comments was quite good. We'll provide a few of them here:
<p>
<blockquote>"<i>Take good care of it, don't leave legacy behind. But still move it forward. by all means remove already deprecated stuff. I feel things can often be don the old and the new way.. And the support forums are full of good recomendations on both old and new. And it's sometimes confusing not being an expert.</i>"</blockquote>
<p>
<blockquote>"<i>Please, single set of bean annotations. Not mixture of CDI, EJB and JSF</i>"</blockquote>
<p>
<blockquote>"<i>Externalize configuration for both AS domain and the app for all configurable properties. - All AS settings must be configurable via command line.</i>"</blockquote>
<p>
<blockquote>"<i>Make it easier to have something between a full application server and just a few features (i.e. I only need JSF, JAX-WS, JavaMail, and DB, but not JPA and EJB, etc.) so they don't have to be manually added in the app or grafted into the servlet container in some non-standard way. Also, I'd prefer to be able to easily choose which technologies (JSF: Mojarra vs MyFaces, JAX-WS: Metro vs Apache CXF, etc.). Just a general thing to watch out for: Don't assume all users will want to use Maven; be sure you provide another way to download.</i>"</blockquote>
<h3>Tag cloud</h3>
<p>
<img src="https://cdn.rawgit.com/arjantijms/javaee2018-report/master/15-tag.svg" width="70%" height="70%">Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com2tag:blogger.com,1999:blog-4498889353428710313.post-85849056202383878502018-03-15T07:54:00.000-07:002018-05-03T06:08:13.084-07:00Java EE Survey 2018At OmniFaces we poll the community from <a href="http://arjan-tijms.omnifaces.org/2015/03/the-most-popular-java-ee-servers-in.html">time</a> to <a href="http://arjan-tijms.omnifaces.org/2017/06/should-community-take-over-jsfnext-or.html">time</a> about Java EE and related technologies. With all the changes that are about to happen with the move of <a href="https://github.com/javaee">Java EE</a> to <a href="https://github.com/eclipse-ee4j">Eclipse</a> and the subsequent <a href="http://www.tomitribe.com/blog/2018/02/java-ee-to-jakarta-ee/">renaming to Jakarta EE</a>, we expanded the survey a little for this year.
<p>
In the 2018 edition, there are 4 categories of questions:
<ul>
<li>Current usage of Java EE</li>
<li>Servlet containers</li>
<li>APIs related to Java EE</li>
<li>The future of Java EE / Jakarta EE</li>
</ul>
<p>
Jakarta EE provides the opportunity to revitalise and modernise Java EE, but in order to do that it's more important than ever that we know what matters to all of its users out there.
<p>
So therefor we'd like to invite all Java EE users to participate in
<b><a href="https://surveymonkey.com/r/javaee-2018-omnifaces">The Java EE Survey 2018</a></b>
Update: Survey now closedArjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-70347209245106549782018-03-07T14:51:00.001-08:002018-03-07T14:52:44.450-08:00Payara 5 RC1 available for testingWe are happy to announce that Payara 5 release candidate 1 is now available for <a href="https://payara.fish/upstream_builds">download</a>.
<p>
Payara 5 is the first release that will include all of the Java EE 8 and MicroProfile 1.2 components, including a special build of Mojarra (JSF 2.3) based on the 2.4 master in which a lot of refactoring has been done, and a special build of Soteria (Java EE Security) based on the 1.1 master with several bug fixes.
<p>
The full list of changes are available from the links given below:
<ul>
<li><a href="https://github.com/payara/Payara/milestone/23?closed=1">Changes in Payara 5 RC 1</a></li>
<li><a href="https://github.com/payara/Payara/milestone/22?closed=1">Changes in Payara 5 Beta 2</a></li>
<li><a href="https://github.com/payara/Payara/milestone/17?closed=1">Changes in Payara 5 Beta 1</a></li>
<li><a href="https://github.com/payara/Payara/milestone/19?closed=1">Changes in Payara 5 Alpha 3</a></li>
<li><a href="https://github.com/payara/Payara/milestone/18?closed=1">Changes in Payara 5 Alpha 2</a></li>
<li><a href="https://github.com/payara/Payara/milestone/16?closed=1">Changes in Payara 5 Alpha 1</a></li>
</ul>
<p>
Payara 5 runs all the <a href="https://github.com/javaee-samples/javaee7-samples">Java EE 7 samples</a>, all the <a href="https://github.com/javaee-samples/javaee8-samples">Java EE 8 samples</a> and all of the <a href="https://github.com/javaee-samples/microprofile1.2-samples">MicroProfile 1.2 samples</a>.
<p>
If no major bugs surface Payara 5 Final should be released soon.
<p>
<i>Arjan Tijms</i>
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-17029312200735702572017-08-23T08:02:00.000-07:002017-08-23T12:19:09.612-07:00Dynamically adding an interceptor to a build-in CDI beanIn Java EE's CDI, beans can be augmented via 2 artefacts; <a href="https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#decorators">Decorators</a> and <a href="https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#interceptors">Interceptors</a>.
<p>
<b>Decorators</b> are typically owned by the application code and can decorate a bean that's shipped by the container (<a href="https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#additional_builtin_beans">build-in beans</a>) or a library.
<p>
<b>Interceptors</b> are typically shipped by a library and can be applied (bound) to a bean that's owned by the application.
<p>
So how do you bind a library shipped interceptor to a library shipped/build-in bean? In CDI 1.2 and before this wasn't really possible, but in CDI 2.0 we can take advantage of the new <a href="https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#interception_factory">InterceptionFactory</a> to do just this. It's not entirely trivial yet, but it's doable. In this article we'll demonstrate how to apply the <a href="https://javaee.github.io/security-api/apidocs/javax/security/enterprise/authentication/mechanism/http/RememberMe.html">@RememberMe</a> interceptor binding from the new Java EE 8 Security spec to a build-in bean of type <a href="https://javaee.github.io/security-api/apidocs/javax/security/enterprise/authentication/mechanism/http/HttpAuthenticationMechanism.html">HttpAuthenticationMechanism</a>, which is from the Security spec as well.
<p>
First we configure our authentication mechanism by means of the following annotation:
<pre class="brush: java;">
@BasicAuthenticationMechanismDefinition(
realmName="foo"
)
</pre>
<p><small> </small>
<p>
This will cause the container to enable a build-in bean with interface type <i>HttpAuthenticationMechanism</i>, but having an unknown (vendor specific) implementation.
<p>
Next we'll definite an <a href="https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#alternatives">alternative</a> for this bean via a CDI producer:
<pre class="brush: java;">
@Alternative
@Priority(500)
@ApplicationScoped
public class ApplicationInit {
@Produces
public HttpAuthenticationMechanism produce(InterceptionFactory<HttpAuthenticationMechanismWrapper> interceptionFactory, BeanManager beanManager) {
return ...
}
</pre>
<small><i>Note that perhaps somewhat counter intuitively the <a href="http://docs.oracle.com/javaee/7/api/javax/enterprise/inject/Alternative.html">@Alternative</a> annotation is put on the bean hosting the producer method, not on the producer method itself.</i></small>
<p>
A small challenge here is to obtain the bean with type <i>HttpAuthenticationMechanism</i> that would have been chosen by the CDI runtime had our producer not been there. For a decorator this is easy as CDI makes that exact bean injectable via the <a href="https://docs.jboss.org/cdi/api/2.0/javax/enterprise/inject/Decorated.html">@Decorated</a> qualifier. Here we'll have to do this manually. One way is to get all the beans of type <i>HttpAuthenticationMechanism</i> from the bean manager (this will include both alternatives and non-alternatives), filter ourselves from that set and then let the bean manager resolve the set to the one that would be chosen for injection. We then create a reference for that chosen bean.
<p>
The following shows this in code:
<pre class="brush: java;">
HttpAuthenticationMechanism mechanism =
createRef(
beanManager.resolve(
beanManager.getBeans(HttpAuthenticationMechanism.class)
.stream()
.filter(e -> !e.getBeanClass().equals(ApplicationInit.class))
.collect(toSet())),
beanManager);
</pre>
<p><small> </small>
<p>
With <i>createRef</I> being defined as:
<pre class="brush: java;">
HttpAuthenticationMechanism createRef(Bean<?> bean, BeanManager beanManager) {
return (HttpAuthenticationMechanism)
beanManager.getReference(
bean,
HttpAuthenticationMechanism.class,
beanManager.createCreationalContext(bean));
}
</pre>
<p><small> </small>
<p>
We now have an instance to the bean to which we like to apply the interceptor binding. Unfortunately, there's a somewhat peculiar and very nasty note in the CDI spec regarding the method that creates a proxy with the required interceptor attached:
<blockquote>
<i>If the provided instance is an internal container construct (such as client proxy), non-portable behavior results.</i>
</blockquote>
<p>
Since the <i>HttpAuthenticationMechanism</i> is a client proxy (it's application scoped by spec definition) we have no choice but to introduce some extra ceremony here and that's by providing a wrapper ourselves. The interceptor will be applied to the wrapper then, and the wrapper will delegate to the actual <i>HttpAuthenticationMechanism</i> instance:
<p>
<pre class="brush: java;">
HttpAuthenticationMechanismWrapper wrapper =
new HttpAuthenticationMechanismWrapper(mechanism);
</pre>
<p><small> </small>
<p>
Having our <i>HttpAuthenticationMechanism</i> instance ready, we can now dynamically configure an annotation instance. Such instance can be created via CDI's provided <a href="https://docs.jboss.org/cdi/api/2.0/javax/enterprise/util/AnnotationLiteral.html">AnnotationLiteral</a> helper type:
<pre class="brush: java;">
interceptionFactory.configure().add(
new RememberMeAnnotationLiteral(
86400, "", // cookieMaxAgeSeconds
false, "", // cookieSecureOnly
true, "", // cookieHttpOnly
"JREMEMBERMEID", // cookieName
true, "" // isRememberMe
)
);
</pre>
<p><small> </small>
<p>
Finally, we create the above mentioned new proxy with the configured interceptor binding applied to it using the interception factory's createInterceptedInstance method and return this from our producer method:
<pre class="brush: java;">
return interceptionFactory.createInterceptedInstance(
new HttpAuthenticationMechanismWrapper(wrapper));
</pre>
<p><small> </small>
<p>
A full example can be found in the <a href="https://github.com/javaee-samples/javaee8-samples/blob/master/security/dynamic-rememberme/src/main/java/org/javaee8/security/dynamic/rememberme/ApplicationInit.java">Java EE 8 samples project</a>.
<p>
Note that there's a small caveat here; if the Interceptor needs access to the interceptor bindings (which is almost always the case when the binding has attributes), you can't just inspect the target type as one would usually do in CDI 1.2 and earlier code. The interceptor binding annotation is not physically present on the type. At the moment it's <a href="http://lists.jboss.org/pipermail/cdi-dev/2017-August/009978.html">not entirely clear</a> how to obtain these in a portable way. The interceptors in the Java EE Security RI (Soteria) uses an <a href="https://github.com/javaee/security-soteria/blob/master/impl/src/main/java/org/glassfish/soteria/cdi/RememberMeInterceptor.java#L198">RI specific way</a> for now.
<p>
The example was <a href="https://travis-ci.org/javaee-samples/javaee8-samples/builds/267394312">tested</a> on <a href="https://www.payara.fish">Payara Server</a> 5, of which a snapshot can be downloaded from the <a href="https://oss.sonatype.org/content/repositories/snapshots/fish/payara/distributions/payara/5.0.0.173-SNAPSHOT/">snapshot repository</a>. An initial alpha will be released very soon, but in the mean time the latest version can be downloaded here: <br/> <a href="https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=fish.payara.distributions&a=payara&v=5.0.0.173-SNAPSHOT&p=zip">payara-5.0.0.173-SNAPSHOT.zip</a>.
<p>
<i>Arjan Tijms</i>
Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0tag:blogger.com,1999:blog-4498889353428710313.post-32063413570104150632017-08-17T05:34:00.001-07:002017-08-17T05:34:09.081-07:00Extensionless URLs with JSF 2.3An extensionless URL is a URL without a final suffix like <i>.xhtml</i>, <i>.html</i>, <i>.jsp</i>, etc. Such a suffix is seen as technical "clutter" that's hard to remember for humans. Servers often need it though to route a request to the right controller.
<p>
JSF, a Java EE MVC framework, has supported extensionless URLs for some time via PrettyFaces (now merged to the general <a href="https://github.com/ocpsoft/rewrite">Rewrite</a> framework) and <a href="http://arjan-tijms.omnifaces.org/2013/03/easy-extensionless-urls-in-jsf-with.html">OmniFaces</a>. Both of these solutions used various workarounds to trick JSF into working with extensionless URLs.
<p>
Though JSF 2.3 does, unfortunately, still not support extensionless URLs fully out of the box via e.g. a single parameter, it can provide support for it by basically combining the new support for <a href="http://arjan-tijms.omnifaces.org/p/jsf-23.html#1260">exact mapping</a> and the API for <a href="http://arjan-tijms.omnifaces.org/p/jsf-23.html#1435">obtaining a list of all view resources</a>. Additionally combining this with the Servlet 3.1 feature for dynamically adding Servlet mappings and some JDK8 streaming and lambdas, makes it possible to enable extensionless support with just 2 statements (albeit somewhat long statements):
<p>
<pre class="brush: java;">
@WebListener
public class MappingInit implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
FacesContext context = FacesContext.getCurrentInstance();
sce.getServletContext()
.getServletRegistrations()
.values()
.stream()
.filter(e -> e.getClassName().equals(FacesServlet.class.getName()))
.findAny()
.ifPresent(
reg -> context.getApplication()
.getViewHandler()
.getViews(context, "/", RETURN_AS_MINIMAL_IMPLICIT_OUTCOME)
.forEach(e -> reg.addMapping(e)));
}
}
</pre>
<p>
What the above code does is finding the existing <i>FacesServlet</i>, then getting all views for the entire application in a form that happens to be exactly suitable for extensionless URLs, and then adding each of them as mapping to the <i>FacesServlet</i> we previously found.
<p>
After adding the above shown <i>WebListener</I> to an application, its view can be requested via URLs like <i>example.com/login</i>, <i>example.com/users/all</i> etc.
<p>
The example was <a href="https://travis-ci.org/javaee-samples/javaee8-samples/builds/265365535">tested</a> on <a href="https://www.payara.fish">Payara Server</a> 5, of which a snapshot can be downloaded from the <a href="https://oss.sonatype.org/content/repositories/snapshots/fish/payara/distributions/payara/5.0.0.173-SNAPSHOT/">snapshot repository</a>. An initial alpha will be released very soon, but in the mean time the latest version can be downloaded here: <br/> <a href="https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=fish.payara.distributions&a=payara&v=5.0.0.173-SNAPSHOT&p=zip">payara-5.0.0.173-SNAPSHOT.zip</a>.
<p>
<i>Arjan Tijms</i>Arjan Tijmshttp://www.blogger.com/profile/08548593340781885396noreply@blogger.com0