Skip to main content

JSF, RichFaces, Spring, Hibernate – lets make development easy.

The goal of this article is to show you how you can use Hibernate, Spring and JSF 1.2 in the most easiest way.

Used technologies :

  • maven 2
  • JSF 1.2 (MyFaces)
  • Spring 2.5.6
  • Hibernate 3.2.1.GA

In the example I will use mysql just for the configuration. You can use whatever you want. The goal that we want is to use Spring for management of transactions and as IoC container. The beast way for us is to make everything spring beans. In typical application we will have Services, DAOs, Entity objects and JSF managed beans. We will make all of them spring beans and use @Autowired annotation (included in Spring). We will use GenericDAO implementation which is explained in this article: http://gochev.blogspot.com/2009/08/hibernate-generic-dao.html.

First lets create a maven 2 project and add replace update it’s pom.xml to looks like this, note that the pom is big we will explain important sections after the whole content.

<?xml version="1.0" encoding="UTF-8"?>

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

      <modelVersion>4.0.0</modelVersion>

      <groupId>myproject-web</groupId>

      <artifactId>myproject-web</artifactId>

      <packaging>war</packaging>

      <version>0.0.1-SNAPSHOT</version>

      <name>A custom project using myfaces</name>

      <url>http://www.myorganization.org</url>

 

      <build>

            <finalName>myproject-web</finalName>

            <plugins>

                  <plugin>

                        <!--This plugin allows to run the example using mvn jetty:run -->

                        <groupId>org.mortbay.jetty</groupId>

                        <artifactId>maven-jetty-plugin</artifactId>

                        <version>6.1.8</version>

                        <configuration>

                             <scanIntervalSeconds>10</scanIntervalSeconds>

                        </configuration>

                  </plugin>

                  <plugin>

                        <artifactId>maven-compiler-plugin</artifactId>

                        <configuration>

                              <source>1.5</source>

                              <target>1.5</target>

                        </configuration>

                  </plugin>

 

                  <plugin>

                        <artifactId>maven-eclipse-plugin</artifactId>

                        <configuration>

                              <wtpversion>2.0</wtpversion>

                             <wtpapplicationxml>true</wtpapplicationxml>

                              <wtpmanifest>true</wtpmanifest>

                              <downloadSources>true</downloadSources>

                              <downloadJavadocs>true</downloadJavadocs>

                          <manifest>${basedir}/src/main/resources/META-INF/MANIFEST.MF</manifest>

                        </configuration>

 

                  </plugin>

            </plugins>

      </build>

      <repositories>

            <repository>

                  <releases>

                        <enabled>false</enabled>

                  </releases>

                  <snapshots>

                        <enabled>true</enabled>

                  </snapshots>

                  <id>apache-maven-snapshots</id>

                  <url>http://people.apache.org/repo/m2-snapshot-repository</url>

            </repository>

            <repository>

                  <id>java.net</id>

                  <url>http://download.java.net/maven/1</url>

                  <layout>legacy</layout>

            </repository>

            <repository>

                  <id>java.net2</id>

                  <url>http://download.java.net/maven/2</url>

                  <layout>legacy</layout>

            </repository>

            <repository>

                  <id>repository.jboss.com</id>

                  <url>http://repository.jboss.com/maven2/</url>

                  <layout>default</layout>

            </repository>

            <repository>

                  <id>repo1</id>

                  <name>repo1</name>

                  <url>http://repo1.maven.org/maven2/</url>

                  <releases>

                        <updatePolicy>never</updatePolicy>

                  </releases>

            </repository>

      </repositories>

 

      <!-- Project dependencies -->

      <dependencies>

 

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-core</artifactId>

                  <version>2.5.6</version>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-beans</artifactId>

                  <version>2.5.6</version>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-context</artifactId>

                  <version>2.5.6</version>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-context-support</artifactId>

                  <version>2.5.6</version>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-orm</artifactId>

                  <version>2.5.6</version>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-aop</artifactId>

                  <version>2.5.6</version>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-jdbc</artifactId>

                  <version>2.5.6</version>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-web</artifactId>

                  <version>2.5.6</version>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-tx</artifactId>

                  <version>2.5.6</version>

            </dependency>

            <dependency>

                  <groupId>mysql</groupId>

                  <artifactId>mysql-connector-java</artifactId>

                  <version>5.0.4</version>

                  <scope>compile</scope>

            </dependency>

 

            <dependency>

                  <groupId>javax.el</groupId>

                  <artifactId>el-api</artifactId>

                  <version>1.0</version>

                  <scope>provided</scope>

            </dependency>

            <dependency>

                  <groupId>org.hibernate</groupId>

                  <artifactId>hibernate-entitymanager</artifactId>

                  <version>3.2.1.GA</version>

            </dependency>

            <dependency>

                  <groupId>org.apache.myfaces.core</groupId>

                  <artifactId>myfaces-api</artifactId>

                  <version>1.2.5</version>

                  <scope>compile</scope>

            </dependency>

            <dependency>

                  <groupId>org.apache.myfaces.core</groupId>

                  <artifactId>myfaces-impl</artifactId>

                  <version>1.2.5</version>

                  <scope>compile</scope>

            </dependency>

            <dependency>

                  <groupId>org.apache.myfaces.tomahawk</groupId>

                  <artifactId>tomahawk</artifactId>

                  <version>1.1.6</version>

                  <scope>runtime</scope>

                  <exclusions>

                        <exclusion>

                              <groupId>javax.servlet</groupId>

                              <artifactId>jstl</artifactId>

                        </exclusion>

                  </exclusions>

            </dependency>

            <dependency>

                  <groupId>jstl</groupId>

                  <artifactId>jstl</artifactId>

                  <version>1.2</version>

                  <scope>runtime</scope>

            </dependency>

 

            <dependency>

                  <groupId>com.sun.facelets</groupId>

                  <artifactId>jsf-facelets</artifactId>

                  <version>1.1.14</version>

            </dependency>

 

            <dependency>

                  <groupId>junit</groupId>

                  <artifactId>junit</artifactId>

                  <version>4.0</version>

                  <scope>test</scope>

            </dependency>

            <dependency>

                  <groupId>org.richfaces.framework</groupId>

                  <artifactId>richfaces-impl</artifactId>

                  <version>3.2.2.SR1</version>

                  <scope>compile</scope>

            </dependency>

            <dependency>

                  <groupId>org.richfaces.ui</groupId>

                  <artifactId>richfaces-ui</artifactId>

                  <version>3.2.2.SR1</version>

                  <scope>compile</scope>

            </dependency>

            <dependency>

                  <groupId>log4j</groupId>

                  <artifactId>log4j</artifactId>

                  <version>1.2.15</version>

                  <exclusions>

                        <exclusion>

                              <groupId>javax.mail</groupId>

                              <artifactId>mail</artifactId>

                        </exclusion>

                        <exclusion>

                              <groupId>com.sun.jdmk</groupId>

                              <artifactId>jmxtools</artifactId>

                        </exclusion>

                        <exclusion>

                              <groupId>com.sun.jmx</groupId>

                              <artifactId>jmxri</artifactId>

                        </exclusion>

                        <exclusion>

                              <groupId>javax.jms</groupId>

                              <artifactId>jms</artifactId>

                        </exclusion>

                  </exclusions>

            </dependency>

            <dependency>

                  <groupId>javax.servlet</groupId>

                  <artifactId>servlet-api</artifactId>

                  <version>2.5</version>

                  <scope>provided</scope>

            </dependency>

            <dependency>

                  <groupId>c3p0</groupId>

                  <artifactId>c3p0</artifactId>

                  <version>0.9.1.2</version>

            </dependency>

           

      </dependencies>

</project>

Most of you don't need explanation but for the rest I will explain the most strange sections. Starting from last one c3p0 – I use it because sometimes mysql closes my idle connection which are in the connection pool. The c3p0 is used to execute test query every X minutes like SELECT 1. The dependancy javax.servlet you dont need it because you deploy on web container but I’ve added it because sometimes I need to cast somethink to HttpServletRequest or HttpSession and I want to have it in my eclipse classpath. Log4j is a must for every project that’s why it is included here. The other dependancies are richfaces, jsf, facelets, hibernate and spring I don't see something strange there so if you don't understand something post a comment.

Next we will use Spring right ? so lets paste the applicationContext.xml ( note that it is not big because we will use @Autowired and @Component to autowire and to register our spring beans ).

<?xml version="1.0" encoding="UTF-8"?>

<beans

      xmlns="http://www.springframework.org/schema/beans"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xmlns:context="http://www.springframework.org/schema/context"

    xmlns:tx="http://www.springframework.org/schema/tx"

      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd

      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd

    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"

     default-autowire="byName">

      

      <context:annotation-config/>

      <tx:annotation-driven proxy-target-class="true" />

     

      <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">

      </bean>

     

      <context:component-scan base-package="org.joke.myproject">

      </context:component-scan>

     

       <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

          <property name="jdbcUrl"><value>jdbc:mysql://localhost:3306/asomtsp?autoReconnect=true&amp;characterEncoding=utf8</value></property>

          <property name="driverClass"><value>com.mysql.jdbc.Driver</value></property>

          <property name="user"><value>root</value></property>

          <property name="password"><value>12345678</value></property>

          <property name="maxStatements"><value>0</value></property>

          <property name="maxIdleTime"><value>1800</value></property>

          <property name="minPoolSize"><value>5</value></property>

          <property name="maxPoolSize"><value>150</value></property>

          <property name="initialPoolSize"><value>20</value></property>

          <property name="acquireIncrement"><value>5</value></property>

          <property name="numHelperThreads"><value>10</value></property> 

          <property name="idleConnectionTestPeriod"><value>3600</value></property>

            <property name="preferredTestQuery"><value>select 1;</value></property>

      </bean>

     

      <bean id="sessionFactory"

 class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

            <property name="configLocation" value="classpath:hibernate.cfg.xml">

            </property>

            <property name="dataSource" ref="dataSource"></property>

      </bean>

</beans>

The default-autowire="byName" attribute is used because I don't want to tell ref bean ref bean for each bean :).

The tag 'context:annotation-config' tells spring to go the annotation way.

The tag 'context:component-scan' tells spring to look for annotated classes in the specified package. Once you put this tag you do not need the 'context:annotation-config' tag.

Sometimes when we auto wire by type there may be multiple beans of the same type (or inherited type). One case is if you define multiple datsasources. How do you tell your bean in that case which one to pick. In this case use @Qualifier("beanid") to select the specific one.

I don't think I have to explain something about transactionManager and dataSource. If you have questions feel free to post a comment.

Next the hibernate.cfg.xml. Since all my database related configurations are in the applicationContext.xml the hibernate.cfg.xml contains only all my mapped classes needed for sessionFactory.

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

      <session-factory>

            <!-- SQL dialect -->

            <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

            <!-- Enable formatted SQL in the logs -->

            <property name="format_sql">true</property>

            <!-- Hibernate mappings references -->

            <mapping class="org.joke.myproject.entity.Message" />

      </session-factory>

</hibernate-configuration>

I have only one entity called Messages and I’ve used annotations for mappings not another xml file. You can use whatever you want annotations or mapping.xml file. If you are using xml file for mappings you will have <mapping resource="Messages.hbm.xml"/> instead of mapping class.

Almost finished. Lets integrate now Spring with JSF. We will want to use spring container for creating a JSF managed beans. So open faces-config.xml and add the fallowing lines  in the application tag. Full example looks like :

<?xml version="1.0" encoding="UTF-8"?>

<faces-config xmlns="http://java.sun.com/xml/ns/javaee"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"

      version="1.2">

      <!—navigation rules goes here -->

      <application>

         <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>

      </application>

</faces-config>

After adding the SpringBeanFacesELResolver lets do the final step : web.xml

<?xml version="1.0"?>

 

      <!--

            * Licensed to the Apache Software Foundation (ASF) under one * or more

            contributor license agreements. See the NOTICE file * distributed with

            this work for additional information * regarding copyright ownership.

            The ASF licenses this file * to you under the Apache License, Version

            2.0 (the * "License"); you may not use this file except in compliance

            * with the License. You may obtain a copy of the License at * *

            http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by

            applicable law or agreed to in writing, * software distributed under

            the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES

            OR CONDITIONS OF ANY * KIND, either express or implied. See the

            License for the * specific language governing permissions and

            limitations * under the License.

      -->

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"

      version="2.4">

 

      <description>myproject web.xml</description>

      <session-config>

       <session-timeout>30</session-timeout>

    </session-config>

      <context-param>

            <param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL</param-name>

            <param-value>true</param-value>

      </context-param>

 

      <!--

            Configure tomahawk taglib <context-param>

            <param-name>facelets.LIBRARIES</param-name>

            <param-value>/WEB-INF/tomahawk.taglib.xml</param-value>

            </context-param>

      -->

      <!-- Use Documents Saved as *.xhtml -->

      <context-param>

            <param-name>javax.faces.DEFAULT_SUFFIX</param-name>

            <param-value>.xhtml</param-value>

      </context-param>

 

      <!-- Special Debug Output for Development -->

      <context-param>

            <param-name>facelets.DEVELOPMENT</param-name>

            <param-value>true</param-value>

      </context-param>

 

      <context-param>

            <param-name>javax.faces.STATE_SAVING_METHOD</param-name>

            <param-value>client</param-value>

      </context-param>

      <context-param>  

            <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>

            <param-value>20</param-value>

      </context-param>

      <context-param>

            <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>

            <param-value>true</param-value>

      </context-param>

      <context-param>

            <param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name>

            <param-value>true</param-value>

      </context-param>

      <context-param>

            <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>

            <param-value>true</param-value>

      </context-param>

      <context-param>

            <param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>

            <param-value>false</param-value>

      </context-param>

      <context-param>

            <param-name>org.apache.myfaces.PRETTY_HTML</param-name>

            <param-value>true</param-value>

      </context-param>

      <context-param>

            <param-name>org.apache.myfaces.AUTO_SCROLL</param-name>

            <param-value>true</param-value>

      </context-param>

 

      <context-param>

            <param-name>org.apache.myfaces.SECRET</param-name>

            <param-value>NzY1NDMyMTA=</param-value>

      </context-param>

 

      <context-param>

            <param-name>org.apache.myfaces.VALIDATE</param-name>

            <param-value>true</param-value>

      </context-param>

 

      <context-param>

            <param-name>org.apache.myfaces.READONLY_AS_DISABLED_FOR_SELECTS</param-name>

            <param-value>true</param-value>

      </context-param>

 

      <context-param>

            <param-name>org.apache.myfaces.ADD_RESOURCE_CLASS</param-name>

            <param-value>

                  org.apache.myfaces.renderkit.html.util.DefaultAddResource

            </param-value>

      </context-param>

 

      <context-param>

            <param-name>org.apache.myfaces.RESOURCE_VIRTUAL_PATH</param-name>

            <param-value>/faces/myFacesExtensionResource</param-value>

      </context-param>

 

      <context-param>

            <param-name>org.apache.myfaces.CHECK_EXTENSIONS_FILTER</param-name>

            <param-value>true</param-value>

      </context-param>

 

      <context-param>

            <param-name>javax.faces.PARTIAL_STATE_SAVING_METHOD</param-name>

            <param-value>false</param-value>

      </context-param>

      <context-param>

            <param-name>org.richfaces.SKIN</param-name>

            <param-value>blueSky</param-value>

      </context-param>

      <context-param>

            <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>

            <param-value>com.sun.facelets.FaceletViewHandler</param-value>

      </context-param>

      <filter>

            <display-name>RichFaces Filter</display-name>

            <filter-name>richfaces</filter-name>

            <filter-class>org.ajax4jsf.Filter</filter-class>

      </filter>

      <!-- Extensions Filter -->

      <filter>

            <filter-name>extensionsFilter</filter-name>

            <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>

            <init-param>

                  <param-name>uploadMaxFileSize</param-name>

                  <param-value>100m</param-value>

            </init-param>

            <init-param>

                  <param-name>uploadThresholdSize</param-name>

                  <param-value>100k</param-value>

            </init-param>

      </filter>

      <filter>

            <filter-name>sessionFilter</filter-name>

            <filter-class>

                  org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>

      </filter>

      <filter-mapping>

            <filter-name>sessionFilter</filter-name>

            <url-pattern>*.jsf</url-pattern>

      </filter-mapping>

 

      <filter-mapping>

            <filter-name>richfaces</filter-name>

            <servlet-name>Faces Servlet</servlet-name>

            <dispatcher>REQUEST</dispatcher>

            <dispatcher>FORWARD</dispatcher>

            <dispatcher>INCLUDE</dispatcher>

      </filter-mapping>

      <filter-mapping>

            <filter-name>extensionsFilter</filter-name>

            <url-pattern>*.jsf</url-pattern>

      </filter-mapping>

      <filter-mapping>

            <filter-name>extensionsFilter</filter-name>

            <url-pattern>/faces/*</url-pattern>

      </filter-mapping>

 

      <!-- Listener, to allow Jetty serving MyFaces apps -->

      <listener>

            <listener-class>

                  org.apache.myfaces.webapp.StartupServletContextListener</listener-class>

      </listener>

      <!--  spring integration  -->

      <listener>

            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

      </listener>

      <listener>

            <listener-class>

                  org.springframework.web.context.request.RequestContextListener</listener-class>

      </listener>

 

      <!-- Faces Servlet -->

      <servlet>

            <servlet-name>Faces Servlet</servlet-name>

            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>

            <load-on-startup>1</load-on-startup>

      </servlet>

 

      <!-- Faces Servlet Mapping -->

      <servlet-mapping>

            <servlet-name>Faces Servlet</servlet-name>

            <url-pattern>*.jsf</url-pattern>

      </servlet-mapping>

 

      <!-- Welcome files -->

      <welcome-file-list>

            <welcome-file>index.jsp</welcome-file>

            <welcome-file>index.html</welcome-file>

      </welcome-file-list>

 

</web-app>

Most of the parts are from the myfaces implementation. The important aspects are :

RichFaces integration using

org.richfaces.SKIN param and richfaces filter (org.ajax4jsf.Filter). 


You can read about richfaces integration here:http://docs.jboss.org/richfaces/3.3.1.GA/en/devguide/html_single/


For jetty+myfaces we need to use this listener : org.apache.myfaces.webapp.StartupServletContextListener



And for Spring integration we need this two listeners : org.springframework.web.context.ContextLoaderListener and org.springframework.web.context.request.RequestContextListener



Thats ALL!


Now Lets start coding :)


Our Managed Beans will dont need any XML configuration they will look like this :



@Component


@Scope("request")


public class MessagesBean {



      @Autowired


      private MessagesService messagesService;


//use messagesService for what you want



}


 


The services are spring beans ( have @Component annotation) and are autowired in JSF Managed Beans/ Backing Beans. Our services looks like this the @Transaction annotation is used for creating transaction. You can read about it at  http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html  part : 9.5.6. Using @Transactional.



@Component


public class MessagesService {



      @Autowired


      private MessagesDAO messagesDAO;


@Transactional


      public List<Message> listMessages() {


            List<Message> messages = messagesDAO.findAll();


            return messages;


      }


//use messagesDao for what you want



}


Our DAOs look like this (they are spring beans again and are autowired in service layer).


@Component


public class MessagesDAO extends GenericDaoImpl<Message, Integer> {


 


      @Override


      protected Class<Message> getEntityClass() {


            return Message.class;


      }


//add additional dao methods if you want



}


Finally ! Thats all. After playing a while with project like this you will notice how fast is to create new service, dao, backing bean/managed bean because you don't need to type any XML.




Feel free to post comments and questions.













Comments

Yasen Simeonov said…
Congrats dude,

in general i hate blogs,
but yours is the second which i put in favorites.
I find it very useful, keep going the same way.

Best .. Yasen
Coalas said…
Hi

could you link to this article an archive with maven project ready to import in eclipse?
It would be very helpful, for someone like me ,who is very new to spring and all Java technologies :)

thank you
Chris
imrabti said…
Thank you.

Looks very well organized I really heat the old approach using the faces-context to register the managed beans.

Popular posts from this blog

Use Client Certificate Authentication with Java and RestTemplate

As a follow up of the  http://gochev.blogspot.com/2019/04/convert-pfx-certificate-to-jks-p12-crt.html  we now have a keystore and a truststore (if anyone needs) and we will use this keystore to send client side authentication using Spring's RestTemplate . First copy your keystore.jks and truststore.jks in your classpath, no one wants absolute paths right ?:) Again a reminder  The difference between truststore and keystore if you are not aware is(quote from the   JSSE ref guide ) :   TrustManager: Determines whether the remote authentication credentials (and thus the connection) should be trusted. KeyManager: Determines which authentication credentials to send to the remote host. The magic happens in the creation of SSLContext. Keep in mind the Spring Boot have a nice RestTemplateBuilder but I will not gonna use it, because someone of you might have an older version or like me, might just use a plain old amazing Spring. If you just want to use the keystore: final Stri

Convert PFX certificate to JKS, P12, CRT

I recently had to use a PFX certificate for client authentication (maybe another post will be coming) and for that reason I had to convert it to a Java keystore (JKS).  We will create BOTH a truststore and a keystore, because based on your needs you might need one or the other.  The difference between truststore and keystore if you are not aware is(quote from the JSSE ref guide : TrustManager: Determines whether the remote authentication credentials (and thus the connection) should be trusted. KeyManager: Determines which authentication credentials to send to the remote host. Ok that's enough what you will need is openssl and Java 7+ ;) ! First let's generate a key from the pfx file, this key is later used for p12 keystore. openssl pkcs12 -in example.pfx -nocerts -out  example .key   Enter Import Password: MAC verified OK Enter PEM pass phrase: Verifying - Enter PEM pass phrase: As shown here you will be asked for the password of the pfx file, l

Use Multiple JVM versions on Mac OS and Linux

Linux Download multiple Java versions and put them into /opt/ If you already have some JDK from ubuntu repo or etc not a big deal, just fix the paths bellow Register them as alternatives sudo update-alternatives --install /usr/bin/java java /opt/java-8-oracle/bin/java 1081 sudo update-alternatives --install /usr/bin/java java /opt/sap-machine-jdk-11.0.3/bin/java 1080 Edit your ~/.bashrc file alias java11='sudo update-alternatives --set java /opt/sapmachine-jdk-11.0.3/bin/java;export JAVA_HOME=/opt/sapmachine-jdk-11.0.3/' alias java8='sudo update-alternatives --set java /opt/java-8-oracle/bin/java;export JAVA_HOME=/usr/lib/java-8-oracle/' SAVE and start a new bash terminal execute java8 to use java8 java11 to use java11 the latest version you have set stays as system wide, but the JAVA_HOME is not :( you can put java8 or java11 as a last line in the bashrc but since it is sudo it will always require password when start and is not gr