EJB with wildfly-services and wildfly-config

All

I think I’ve written here some topics about wildfly-config and EJB setting for client configuration. Let me go deep on this topic this time (these are the previous topics about it: here1 and here2).

Wildfly-config.xml will have its own syntax, but it is quite simple to understand, let see complete example. Basically everything must be in configuration, below authentication client, where we can defined the key stores, ssl contexts, and ssl context rules. Where the rules -> context -> key store. The default authentication rule is used and the defined at the bottom.

<?xml version="1.0" encoding="UTF-8"?>
...
<configuration>
  <authentication-client xmlns="urn:elytron:1.0">
      <!-- key stores-->
      <key-stores>
        <key-store name="qsKeyStore" type="JKS">
          <file name="server.keystore"/>
          <key-store-clear-password password="secret"/>
        </key-store>
      </key-stores>
      <!-- ssl context definition -->
      <ssl-contexts>
        <ssl-context name="aContext">
          <trust-store key-store-name="qsKeyStore"/>
          <cipher-suite selector="DEFAULT"/>
          <protocol names="TLSv1.2"/> <!-- tls v 1.2 -->
        </ssl-context>
      </ssl-contexts>
      <!-- usage -->
      <ssl-context-rules>
            <rule use-ssl-context="aContext"/>
      </ssl-context-rules>

        <!-- authentication rules use teh default configuration -->
        <authentication-rules>
                    <rule use-configuration="default" />
        </authentication-rules>
        <!-- Default configuration defined below \, and used above ^-->
        <authentication-configurations>
            <configuration name="default">
                <sasl-mechanism-selector selector="#ALL" />
                <set-mechanism-properties>
                    <property key="wildfly.sasl.local-user.quiet-auth" value="true" />
                 </set-mechanism-properties>
                <providers>
                    <use-service-loader/>
                </providers>
                <!-- Used for EJB over HTTP, remoting invocations will use transparent auth-->
                <set-user-name name="auser" />
                <credentials>
                    <clear-password password="apassword!" />
                </credentials>
             </configuration>
        </authentication-configurations>
    </authentication-client>
</configuration>

Now, in regards to using wildfly-config.xml, we can just do the following lookup for http and for https:

  <authentication-client xmlns="urn:elytron:1.0">
      <!-- key stores-->
      <key-stores>
        <key-store name="qsKeyStore" type="JKS">
          <file name="server.keystore"/>
          <key-store-clear-password password="secret"/>
        </key-store>
      </key-stores>
      <!-- ssl context definition -->
      <ssl-contexts>
        <ssl-context name="qsSSLContext">
          <trust-store key-store-name="qsKeyStore"/>
          <cipher-suite selector="DEFAULT"/>
          <protocol names="TLSv1.2"/>
        </ssl-context>
      </ssl-contexts>
      <!-- usage -->
      <ssl-context-rules>
            <rule use-ssl-context="qsSSLContext"/>
      </ssl-context-rules>

        <!-- authentication rules use teh default configuration -->
        <authentication-rules>
                    <rule use-configuration="default" />
        </authentication-rules>

And the initial context, for latest Wildfly, we can do as follows:

	//Get Initial Context
	public static Context getInitialContext() throws NamingException{
			Properties props = new Properties();
			props.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
			props.put(Context.PROVIDER_URL,"https://localhost:8443/wildfly-services");// <----  https:8443
			final Context context = new InitialContext(props);
			return context;
	}

So then we have, basically, http:8080/wildfly-services or https:8443/wildfly-services

Create jars and manifest files

All

Continuing my last posts. Let’s create a simple jar with the default content, using the -v option, for verbose (which will tell us exactly what is being added). Example:

jar cvf Example.jar * (or MyClass.class)

And compare with 0 option (which avoids compacting the files, and therefore will be heavier). In some tests Ive done here, the -0 can save considerable space sometimes, 30% in some cases).

jar -c0vf 

Now let’s set the main class with the `-e` option:

#using the v for verbose, f for file, -c for xx, and -e for setting the main file
jar -cvfe ClientJar.jar StandaloneClass Standalone.class

Now, let’s present we want to create a sealed jar, for instance when sending to the customer, to do so let’s add a customized manifest file, so we use the java -cvfm (m to use a custom manifest file), and create a manifest with the following content (with some other customizations):

manifest
sealed <---- set it to sealed

What is more interesting is that creating jars manually, makes me learn much more about the inner compilation of java classes, and the fact that inner classes generates a , like: StandaloneClient$innerclass.class, that is quite expected and obvious, but when creating the jar, so then we need to set jar -cvf *class, to not ended forgetting to add the inner class!

That’s the same if we implement the runnable and such, which makes a StandaloneClient$1.class <— which is de facto an anonymous inner class just because we implemented Runnable. If not, you will clearly face this (and wonder how come this happens):

NoClassDefFound: standaloneclient$1 <---- here

So must of the times, we don’t even bother creating/editing the Manifest file (since the IDE creates it and package it). But it is actually very useful and can come in hand in some scenarios.

Well, I guess that’s all the suggestions for today. Maybe next week I’ll do a blog post about o11y (observability), complementing my posts about java and k8s (and OCP).

Taking the world by storm: Log4Shell vulnerability CVE-2021-44228

All

Friday Nov 10th morning the news of Log4Shell vulnerability (CVE-2021-44228) started to appear, a few hours later several sites were already having their IPs shown in Github, examples were TSLA, twitter, Apple, Amazon, Twitter.

This vulnerability is very much related to one topic I usually post about it here, which is JNDI lookup, and LDAP in the context of EJB for returning Java Objects – aka serialization. And CVE 44228 is basically this, a JNDI lookup().

Updating your JDK for the latest will not save your from this one, but depending on the JDK it will much easier to get it. Explanation:

JDK versionsVulnerability
<8u121Starting with Java 8u121 remote codebase were no longer permitted by default for RMI (but not LDAP).
<=8u191There is a direct path from a controlled JNDI lookup to remote classloading of arbitrary code
8u191>RMI, References and object construction can still happen. Example: Apache Xbean BeanFactory

Solutions were already much much already described, basically updating the log4j or removing the JNDI lookup class. Since from log4j 2.15.0, this behavior has been disabled by default.

javac

All

Javac is this very well known tool will read the class files, .java, and create bytecode. Very useful and can be used with the following options. I think the -cp and -d are the most well known options. However, it has some many features we pretty much overlook that I think it is worth considering a second look (some examples from Nam Ha blog).

For instance, there is also the -verbose, example (from my favorite suite of java programs from Univ of Texas):

[fdemeloj@fdemeloj javac]$ javac -version FilterExample.java 
javac 1.7.0_171 <------------------------------------------------------ yes, javac is default for JDK 7, use alternatives to fix this
...
[fdemeloj@fdemeloj javac]$ javac -verbose First.java 
[parsing started RegularFileObject[First.java]]
[parsing completed 14ms]
[search path for source files: .]
[search path for class files: 
...pulse-java.jar,.]
../rt.jar/java/awt/Frame.class)]]
../rt.jar/java/awt/MenuContainer.class)]]
../rt.jar/java/lang/Object.class)]]
../rt.jar/java/awt/Window.class)]]
../rt.jar/javax/accessibility/Accessible.class)]]
../rt.jar/java/awt/Container.class)]]
...
[wrote RegularFileObject[First.class]]
[total 520ms]
[fdemeloj@fdemeloj javac]$ java First 

And given a certain directory (already there) you can use -d to set the compiled classes there: javac -d classes, so the .class files will be under /classes dir.

Interestingly -Xdiags:verbose (and compact) options does not seem to add much more on top of the verbose, in fact it adds 0 from when comparing to -verbose option, perhaps depending on the issue it shows more. I mean it helps a lot because it will show what is required vs what was found (see below – Driver class):

[fdemeloj@fdemeloj javac]$ $JAVA_HOME/bin/javac -verbose Driver01.java  <--------------------------------------- verbose
[parsing started SimpleFileObject[/home/fdemeloj/Downloads/cases/EJBtests/javac/Driver01.java]]
[parsing completed 29ms]
[loading /modules/java.xml.crypto/module-info.class] 
<<several others>>>
...
Driver01.java:41: error: incompatible types: possible lossy conversion from double to int
            swap(j, range, enterArray);
                 ^
[total 366ms]
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
[fdemeloj@fdemeloj javac]$ $JAVA_HOME/bin/javac -Xdiags:compact Driver01.java  <----------------------------------- compact
Driver01.java:41: error: incompatible types: possible lossy conversion from double to int
            swap(j, range, enterArray);
                 ^
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
[fdemeloj@fdemeloj javac]$ $JAVA_HOME/bin/javac -Xdiags:verbose Driver01.java <----------------------------------- verbose
Driver01.java:41: error: method swap in class Driver01 cannot be applied to given types;
            swap(j, range, enterArray);
            ^
  required: int,int,double[]
  found: double,int,double[]
  reason: argument mismatch; possible lossy conversion from double to int
1 error

And some extra options can be found with –help-extra:


[fdemeloj@fdemeloj javac]$ $JAVA_HOME/bin/javac --help-extra
  --add-exports <module>/<package>=<other-module>(,<other-module>)*
        Specify a package to be considered as exported from its defining module
        to additional modules, or to all unnamed modules if <other-module> is ALL-UNNAMED.
  --add-reads <module>=<other-module>(,<other-module>)*
        Specify additional modules to be considered as required by a given module.
        <other-module> may be ALL-UNNAMED to require the unnamed module.

One the most useful options is actually the Xlint (maybe because of my background in python and python lint process, pep-8 and so forth), I will ended doing a blog post about PMD, Checkstyle, and PetitDej as well:

[fdemeloj@fdemeloj javac]$ $JAVA_HOME/bin/javac -Xlint First.java 
First.java:3: warning: [serial] serializable class First has no definition of serialVersionUID <------ 
class First extends Frame{
^
1 warning

In JDK 11, interestingly it is possible to set –release flag not only sets source and target versions, but it also causes the compiler to use the symbol table for the JDK libraries corresponding to the specified release. This flag was added after and basically replace –source and –target.

Note: On JDK 11, I think I already mentioned this here that you can just run java, instead of javac, and the class will run:

java Hello.java
Hello, so much snow today in MTL!

I think one of the most useful, which makes javac almost like maven, is the ability to halt the compilation in case a warning happens with -Werror so it makes a default error when it seems a warning:

[fdemeloj@fdemeloj javac]$ $JAVA_HOME/bin/javac -Xdoclint:all -Werror First.java 
First.java:3: warning: no comment
class First extends Frame{
^
First.java:5: warning: no comment
First(){
^
First.java:15: warning: no comment
public static void main(String args[]){
                   ^
error: warnings found and -Werror specified
1 error <--------------------------------------------------------------------------- 1 error
3 warnings <------------------------------------------------------------------------ 3 warnings
[fdemeloj@fdemeloj javac]$ $JAVA_HOME/bin/javac -Xdoclint:all First.java 
First.java:3: warning: no comment
class First extends Frame{
^
First.java:5: warning: no comment
First(){
^
First.java:15: warning: no comment
public static void main(String args[]){
                   ^
3 warnings <--------------------------------------------------------------------------- 3 warnings