July 10, 2017

Install MariaDB (MySQL Open Source) on RHEL 7 and JBoss EAP 7 DataSource

First what is MariaDB? "MariaDB is a community-developed fork of the MySQL relational database management system intended to remain free under the GNU GPL. Development is led by some of the original developers of MySQL, who forked it due to concerns over its acquisition by Oracle Corporation." [https://en.wikipedia.org/wiki/MariaDB]

Now lets install MariaDB Server (mariadb-server) and Client (mariadb) on RHEL 7.

yum install mariadb-server mariadb -y

And start it.

# systemctl start mariadb

When installing MariaDB fresh on RHEL7 there is a default user 'root' with empty password. To test this execute as user jboss and run mysql select on system table user:

# sudo -u jboss mysql -u root -e "select Host, User, Password from mysql.user;"

We will now install MySQL JDBC driver to JBoss and configure a test DataSource following https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.0/html-single/configuration_guide/#example_mysql_datasource

# yum install mysql-connector-java -y

After installing the Official JDBC driver for MySQL, we create the EAP module.

# mkdir -p /opt/rh/eap7/root/usr/share/wildfly/modules/com/mysql/main
# ln -s /usr/share/java/mysql-connector-java.jar /opt/rh/eap7/root/usr/share/wildfly/modules/com/mysql/main

# vi /opt/rh/eap7/root/usr/share/wildfly/modules/com/mysql/main/module.xml


  
    
  
  
    
    
  


# chown jboss:jboss -Rv /opt/rh/eap7/root/usr/share/wildfly/modules/com
# restorecon -RFv /opt/rh/eap7/root/usr/share/wildfly/modules/

Now configure EAP 7 datasource.

# vi /opt/rh/eap7/root/usr/share/wildfly/standalone/configuration/standalone.xml
...
        <subsystem xmlns="urn:jboss:domain:datasources:4.0">
            <datasources>
                ...
                <datasource jndi-name="java:jboss/MySqlDS" pool-name="MySqlDS">
                    <connection-url>jdbc:mysql://localhost:3306/test</connection-url>
                    <driver>mysql</driver>
                    <security>
                        <user-name>root</user-name>
                        <password></password>
                    </security>
                    <validation>
                        <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/>
                        <validate-on-match>true</validate-on-match>
                        <background-validation>false</background-validation>
                        <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter"/>
                    </validation>
                </datasource>
                <drivers>
                    <driver name="mysql" module="com.mysql">
                        <driver-class>com.mysql.jdbc.Driver</driver-class>
                        <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
                    </driver>
                    ...
                </drivers>
            </datasources>
        </subsystem>
...

Now lets create a simple web, just containing one JSP file, so inside the war file there is only one JSP file. The code I copied from http://www.java2s.com/Code/Java/JSP/UsingaDataSource.htm, but for it to work with your datasource you need to change the JNDI lookup code and sql statement to.

Context context = new InitialContext();
ds =  (DataSource)context.lookup("java:jboss/MySqlDS");
if (ds != null) {
    conn = ds.getConnection();
    stmt = conn.createStatement();
    result = stmt.executeQuery("select Host, User, Password from mysql.user");
}

July 9, 2017

Configure mod_proxy on RHEL 7 for JBoss EAP 7

In my previous blog I described how to RPM install JBoss EAP 7 on RHEL 7.

Here I will describe how to configure Apache mod_proxy as a Non-load-balancing Proxy.

First install Apache 2.4 and mod_ssl.

# yum install httpd mod_ssl -y

Then configure mod_proxy as Non-load-balancing Proxy.

# vi /etc/httpd/conf.d/ssl.conf
    ...

    # A non-load-balancing proxy
    # https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.0/html-single/configuration_guide/#configure_mod_proxy_apache_http_server
    ProxyPreserveHost On
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/

</VirtualHost>

The final step is to fix SELinux. When you restart Apache and try your proxy you will get error in SSL log.

# cat /etc/httpd/logs/ssl_error_log 
[Thu Jul 06 08:20:09.211374 2017] [proxy:error] [pid 11338] (13)Permission denied: AH00957: HTTP: attempt to connect to 127.0.0.1:8080 (localhost) failed
[Thu Jul 06 08:20:09.211423 2017] [proxy:error] [pid 11338] AH00959: ap_proxy_connect_backend disabling worker for (localhost) for 60s
[Thu Jul 06 08:20:09.211432 2017] [proxy_http:error] [pid 11338] [client 192.168.122.1:60964] AH01114: HTTP: failed to make connection to backend: localhost

And also in syslog

# less /var/log/audit/audit.log
...
type=AVC msg=audit(1499321632.860:445): avc:  denied  { name_connect } for  pid=11300 comm="httpd" dest=8080 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket
...

To fix this add.

# setsebool httpd_can_network_connect 1

If this works add SELinux rule permanently.

# setsebool -P httpd_can_network_connect 1

July 5, 2017

How to RPM Install JBoss EAP 7 on RHEL 7

We will start fresh with a unregistered RHEL 7, so we first register the machine and their enter our username and password.

# subscription-manager register
...

After that we are ready to add EAP7 subscription. You can here use the auto attach feature, but I recommend using a more controlled way, by adding specific pools.

# subscription-manager list --available | less
...
Subscription Name:   JBoss Business Partner Self-Supported NFR
Provides:            Red Hat OpenShift Enterprise JBoss EAP add-on Beta
                     Red Hat JBoss A-MQ Clients
                     Red Hat Single Sign-On
                     Red Hat OpenShift Enterprise JBoss EAP add-on
                     JBoss Enterprise Application Platform
                     Red Hat JBoss Core Services
                     Red Hat JBoss Data Grid
                     JBoss Enterprise Web Server
                     Red Hat JBoss A-MQ Interconnect
...
Pool ID:             XXXXXXXXXXXXXXXXXXXXXXXXX
...
# subscription-manager attach --poolid=XXXXXXXXXXXXXXXXXXXXXXXXX

Now you think we are done, and check active RPM repos, but do not see any EAP repo. Why? Because the are two EAP 7 repos for RHEL7. A Current (always upgrade, i.e. 7.1, 7.2, etc) and a Minor (freeze to specific minor version, e.g. 7.0). I recommend using the Current. For further reading see https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.0/html-single/installation_guide/#choosing_a_repository.

# yum repolist
Loaded plugins: product-id, search-disabled-repos, subscription-manager
repo id                                             repo name                                                               status
rhel-7-server-nfv-rpms/7Server/x86_64               Red Hat Enterprise Linux for Real Time for NFV (RHEL 7 Server) (RPMs)   177
rhel-7-server-rpms/7Server/x86_64                   Red Hat Enterprise Linux 7 Server (RPMs)                                14 589
repolist: 14 766
# subscription-manager repos --list | grep eap-7
Repo ID:   jb-eap-7-for-rhel-7-server-source-rpms
Repo ID:   jb-eap-7-for-rhel-7-server-rpms
Repo ID:   jb-eap-7-for-rhel-7-server-debug-rpms
Repo ID:   jb-eap-7.0-for-rhel-7-server-debug-rpms
Repo ID:   jb-eap-7.0-for-rhel-7-server-source-rpms
Repo ID:   jb-eap-7.0-for-rhel-7-server-rpms
# subscription-manager repos --enable=jb-eap-7-for-rhel-7-server-rpms
# yum repolist
Loaded plugins: product-id, search-disabled-repos, subscription-manager
repo id                                             repo name                                                               status
jb-eap-7-for-rhel-7-server-rpms/7Server/x86_64      JBoss Enterprise Application Platform 7 (RHEL 7 Server) (RPMs)          777
rhel-7-server-nfv-rpms/7Server/x86_64               Red Hat Enterprise Linux for Real Time for NFV (RHEL 7 Server) (RPMs)   177
rhel-7-server-rpms/7Server/x86_64                   Red Hat Enterprise Linux 7 Server (RPMs)                                14 589
repolist: 15 543

When EAP repo in place, please go ahead and install, with groupinstall.

# yum grouplist hidden | grep -i eap
There is no installed groups file.
Maybe run: yum groups mark convert (see man yum)
   JBoss EAP 7
# yum groupinstall "JBoss EAP 7"

And then test it.

# systemctl restart eap7-standalone

# systemctl status eap7-standalone 
● eap7-standalone.service - The WildFly Application Server (standalone mode)
   Loaded: loaded (/usr/lib/systemd/system/eap7-standalone.service; disabled; vendor preset: disabled)
   Active: active (running) since ons 2017-07-05 15:23:10 CEST; 11s ago
 Main PID: 2039 (scl)
   CGroup: /system.slice/eap7-standalone.service
           ├─2039 /usr/bin/scl enable eap7 -- /opt/rh/eap7/root/usr/share/wildfly/bin/launch.sh /usr/lib/jvm/jre-1.8.0 /usr/lib/jvm/jre-1.8.0/bin /opt/rh/eap7/root/usr/share/wildfly/modules /opt/rh/eap7/...
           ├─2040 /bin/bash /var/tmp/sclFd4fWx
           ├─2043 /bin/sh /opt/rh/eap7/root/usr/share/wildfly/bin/launch.sh /usr/lib/jvm/jre-1.8.0 /usr/lib/jvm/jre-1.8.0/bin /opt/rh/eap7/root/usr/share/wildfly/modules /opt/rh/eap7/root/usr/share/wildf...
           ├─2044 /bin/sh /opt/rh/eap7/root/usr/share/wildfly/bin/standalone.sh -c standalone.xml -b 0.0.0.0
           └─2117 /usr/lib/jvm/jre-1.8.0/bin/java -D[Standalone] -server -verbose:gc -Xloggc:/opt/rh/eap7/root/usr/share/wildfly/standalone/log/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseG...

jul 05 15:23:10 localhost.localdomain systemd[1]: Started The WildFly Application Server (standalone mode).
jul 05 15:23:10 localhost.localdomain systemd[1]: Starting The WildFly Application Server (standalone mode)...

June 27, 2017

Postback Lifecycle in JSF 2.0 (EE 6)

"The request-response lifecycle handles two kinds of requests: initial requests and postbacks. An initial request occurs when a user makes a request for a page for the first time. A postback request occurs when a user submits the form contained on a page that was previously loaded into the browser as a result of executing an initial request."

Reference: Oracle Java EE 6 Tutorial The Lifecycle of a JavaServer Faces Application

Getting Started with JSF 2.0 (EE 6)

Introduction

JSF 2.0 is the standard Web Framework that ships with Java EE 6. Here I will build a simple JSF web app to get you started with the build stones.

Maven

With starting with Java EE 6, there is a ONE dependency for all Java EE, namely javax:javaee-api:[6.0|7.0]. A basic pom.xml file for Java EE 6 is.

<?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/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>se.magnuskkarlsson.examples</groupId>
    <artifactId>example-jsf20</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.build.outputEncoding>UTF-8</project.build.outputEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
    </build>
</project>

Deployment Descriptors

Starting with EE 6 the web.xml is no longer compulsory, so here we will skip it.

A new feature in JSF 2.0, is that you do not need to declare navigation in the faces-config.xml, but you need to declare. That is the same thing with CDI. To enable CDI you need to have beans.xml. So we have to deployment descriptors.

  • WEB-INF/faces-config.xml
  • WEB-INF/beans.xml

Another feature in JSF 2.0, is that you can use ordinary CDI annotation instead of JSF specific. This makes one thing less to remember.

So instead of @javax.faces.bean.ManagedBean we can use @javax.inject.Named.

And instead of @javax.faces.bean.RequestScoped we can use @javax.enterprise.context.RequestScoped.

So a simple request scope baking bean for JSF is.

package se.magnuskkarlsson.example.jsf;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
// Shorthand for @Named and @RequestScoped is @javax.enterprise.inject.Model
public class UserBean {

    private String name;

    public String getMessage() {
        return (name != null) ? "Hello " + name : null;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

And finally our simple hello JSF page. Notice the commandButton and action, it points to JSF page hello, i.e. to the page itself.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html">

<h:head>
    <title>Example JSF 2.0 Hello</title>
</h:head>
<h:body>
    <h:form>
        <h:outputLabel value="What is your name?" for="name" />
        <h:inputText id="name" value="${userBean.name}" />
        <h:commandButton value="Submit" action="hello" />
    </h:form>
    <p>
        <h:outputText value="${userBean.message}"
            rendered="${not empty userBean.message}" />
    </p>
</h:body>
</html>

Now build and deploy it to e.g. JBoss EAP 6, the app is accessible from either

http://localhost:8080/example-jsf20-1.0.0-SNAPSHOT/hello.jsf

http://localhost:8080/example-jsf20-1.0.0-SNAPSHOT/faces/hello.xhtml

June 17, 2017

JSF 2.0 Facelets Tag Libraries

Tag Library

"JSP technology is considered to be a deprecated presentation technology for JavaServer Faces. Facelets is a part of the JavaServer Faces specification and also the preferred presentation technology for building JavaServer Faces technology-based applications."

Tag Library URI Prefix Example Contents
JavaServer Faces HTML Tag Library http://java.sun.com/jsf/html h: h:head
h:body
h:outputText
h:inputText
JavaServer Faces component tags for all UIComponent objects
JavaServer Faces Core Tag Library http://java.sun.com/jsf/core f: f:actionListener
f:attribute
Tags for JavaServer Faces custom actions that are independent of any particular render kit
JavaServer Faces Facelets Tag Library http://java.sun.com/jsf/facelets ui: ui:component
ui:insert
Tags for templating
JSTL Core Tag Library http://java.sun.com/jsp/jstl/core c: c:forEach
c:catch
JSTL 1.2 Core Tags
JSTL Functions Tag Library http://java.sun.com/jsp/jstl/functions fn: fn:toUpperCase
fn:toLowerCase
JSTL 1.2 Functions Tags

Reference: Oracle Java EE 6 Tutorial: What Is Facelets?

Facelet Template

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://java.sun.com/jsf/html"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:c="http://java.sun.com/jsp/jstl/core"
 xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<h:head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <h:outputStylesheet library="css" name="default.css" />
 <title>Facelets Template</title>
</h:head>
<h:body>

 <h1>Hello</h1>

</h:body>
</html>