Archive for March, 2017

29
Mar
17

setup maria db jdbc resources in tomcat 9

This page describes how to setup Maria DB JDBC Resources in Tomcat 9 and how to create a servlet based webapp without a web.xml.

Full downloadable source for this page is available here. Corrections and enhancements are welcome, fork, change and push back to GitHub.

Database Drivers

Place the database driver jar file into the server/lib folder.

Define the resource in Tomcat

Place the following into the $CATALINA_BASE/conf/context.xml

  <Resource name="jdbc/batch" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="10000"
               username="username" password="password" driverClassName="org.mariadb.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/test"/>

Please note that if you are running in Eclipse and have Tomcat setup as a WTP project then this file is located in the “Server” project in your eclipse workspace.

Test using Snoop JSP

To test the datasource simply create a snoop jsp to perform a lookup.

Test using your own Servlet

src/main/java/com/test/TestServlet.java

package com.test;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

@WebServlet(urlPatterns = "/testServlet", loadOnStartup = 1)
public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// You may use the following lines to initialize the context.
		// Obtain our environment naming context
		Context initCtx;
		try {
			initCtx = new InitialContext();
			Context envCtx = (Context) initCtx.lookup("java:comp/env");

			// A data source can be obtained by doing the following.
			// Look up our data source
			DataSource ds = (DataSource) envCtx.lookup("jdbc/test");

			// Allocate and use a connection from the pool
			
			// ... use this connection to access the database ...
			try (PrintWriter writer = resp.getWriter(); Connection conn = ds.getConnection();) {
				writer.println("connected: " + !conn.isClosed());
				DatabaseMetaData metadata = conn.getMetaData();
				writer.println("Database Product Name: " + metadata.getDatabaseProductName());
				writer.println("Database Product Version: " + metadata.getDatabaseProductVersion());
				writer.println("Logged User: " + metadata.getUserName());
				writer.println("JDBC Driver: " + metadata.getDriverName());
				writer.println("Driver Version: " + metadata.getDriverVersion());
				writer.println("\n");				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

If you are using the popular spring framework you can do the following


<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/test"/>
    <property name="resourceRef" value="true"/>
 </bean>

Restart and visit http://localhost:8080/test-jndi/testServlet to view the results of the connection.

Full downloadable source for this page is available here.
29
Mar
17

JNDI lookup for a datasource in JBOSS

This page describes how to perform a jndi lookup in JBoss EAP 7. In the past the lookup string was always a confusing mess. Do we use “java/jdbc/dsName” or “java:comp/env” etc… With JBoss EAP 7 its simplified.

If you have a datasource defined in jboss as: java:/test

Example:

                <datasource jta="true" jndi-name="java:/test" pool-name="Test" enabled="true" use-ccm="true">
                    <connection-url>jdbc:mysql://localhost:3306/test</connection-url>
                    <driver-class>org.mariadb.jdbc.Driver</driver-class>
                    <driver>mariadb</driver>
                </datasource>

Getting the datasource is as simple as writing the following anywhere in your application.

	public DataSource getDataSource() throws Exception {
		return (DataSource) (new InitialContext()).lookup("test");
	}
29
Mar
17

Setting up a datasource in JBOSS EAP 7

Go to {JBOSS_HOME}\modules.
Create following directory structure.
JBOSS_HOME}\modules\com\oracle\ojdbc6\main (the “main” as last folder is crucial!)
In that folder put the oracle jdbc jar. For example ojdbc6-11.2.0.3.jar.
In the same folder create a file module.xml
Add this content to the file:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.oracle.ojdbc6">
 <resources>
 <resource-root path="ojdbc6-11.2.0.3.jar"/>
 </resources>
 <dependencies>
 <module name="javax.api"/>
 <module name="javax.transaction.api"/>
 <module name="javax.servlet.api" optional="true"/>
 </dependencies>
</module>

standalone.xml

                    <driver name="mariadb" module="org.mariadb"/>

Using the admin UI add the datasource. The driver should appear in the list of available drivers on the system.

29
Mar
17

JAX-RS Spring based project example

The following page describes how to get a spring context initialized and injected into a rest based project running on JBOSS AS.

Technology Stack

  • JAX-RS
  • Spring
  • JBOSS EAP
Full downloadable source for this page is available here. Corrections and enhancements are welcome, fork, change and push back to GitHub.

Maven Project Configuration

pom.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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>com.test</groupId>
    <artifactId>jboss-helloworld-rs</artifactId>
    <version>20170329</version>
    <packaging>war</packaging>

    <pluginRepositories>
      <pluginRepository>
        <id>numberformat-releases</id>
        <url>https://rawgit.com/numberformat/20130213/master/repo</url>
      </pluginRepository>
    </pluginRepositories>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <version.jboss.spec.javaee.7.0>1.0.3.Final-redhat-2</version.jboss.spec.javaee.7.0>

        <!-- other plug-in versions -->
        <version.war.plugin>2.1.1</version.war.plugin>

        <!-- maven-compiler-plugin -->
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Define the version of the JBoss Java EE APIs we want to import.
                Any dependencies from org.jboss.spec will have their version defined by this
                BOM -->
            <!-- JBoss distributes a complete set of Java EE APIs including
                a Bill of Materials (BOM). A BOM specifies the versions of a "stack" (or
                a collection) of artifacts. We use this here so that we always get the correct
                versions of artifacts. Here we use the jboss-javaee-7.0 stack (you can
                read this as the JBoss stack of the Java EE APIs). You can actually
                use this stack with any version of JBoss EAP that implements Java EE. -->
            <dependency>
                <groupId>org.jboss.spec</groupId>
                <artifactId>jboss-javaee-7.0</artifactId>
                <version>${version.jboss.spec.javaee.7.0}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>4.1.4.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>            
        </dependencies>
    </dependencyManagement>

    <dependencies>

        <!-- Import the CDI API, we use provided scope as the API is included in JBoss EAP -->
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- Import the Common Annotations API (JSR-250), we use provided scope
            as the API is included in JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.annotation</groupId>
            <artifactId>jboss-annotations-api_1.2_spec</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- Import the JAX-RS API, we use provided scope as the API is included in JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.ws.rs</groupId>
            <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
            <scope>provided</scope>
        </dependency>
<!-- Spring -->        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>        
    </dependencies>

    <build>
        <!-- Set the name of the WAR, used as the context root when the app
            is deployed -->
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>${version.war.plugin}</version>
                <configuration>
               <!-- Java EE doesn't require web.xml, Maven needs to catch up! -->
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>github.numberformat</groupId>
                <artifactId>blog-plugin</artifactId>
                <version>1.0-SNAPSHOT</version>
                <configuration>
                <gitUrl>https://github.com/numberformat/wordpress/tree/master/${project.version}/${project.artifactId}</gitUrl>
                </configuration>
            <executions>
              <execution>
                <id>1</id>
                <phase>site</phase>
                <goals>
                  <goal>generate</goal>
                </goals>
              </execution>
            </executions>
            </plugin>            
        </plugins>
    </build>
</project>

Web Configuration and Html files

src/main/webapp/WEB-INF/web.xml

<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <!-- One of the way of activating REST Servises is adding these lines, the server is responsible for adding the corresponding servlet automatically. If the src folder, org.jboss.as.quickstarts.rshelloworld.HelloWorld class has the Annotations to receive REST invocation-->
    <servlet-mapping>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

src/main/webapp/WEB-INF/beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Marker file indicating CDI should be enabled -->
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
      http://xmlns.jcp.org/xml/ns/javaee
      http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    bean-discovery-mode="all">
</beans>

src/main/webapp/index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>helloworld-rs</title>
</head>
<body>

    <p>Choose between <em>JSON</em> or <em>XML</em>:

    <ul>
    	<li><a href="rest/json">JSON</a></li>
        <li><a href="rest/xml">XML</a></li>
    </ul>
</body>
</html>

Java Code

Here we have a spring config via java annotated class.

src/main/java/com/test/SpringConfig.java

package com.test;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * This class replaces the spring xml configuration.
 * 
 */
@Configuration
@ComponentScan("com.test")
@EnableTransactionManagement 
public class SpringConfig {

}

Next we have a context holder class. This is a CDI Bean that will hold a reference to a spring context. This is the only place CDI is used in the project.
src/main/java/com/test/ContextHolder.java

package com.test;

import java.util.Arrays;

import javax.annotation.PostConstruct;
import javax.inject.Singleton;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * A simple CDI service which is able to say hello to someone
 */
@Singleton
public class ContextHolder {

	private AnnotationConfigApplicationContext ctx = null;
	
	@PostConstruct
	void postConstruct() {
        // Initialize the spring framework.
        ctx = new AnnotationConfigApplicationContext();  
        ctx.register(SpringConfig.class);
        ctx.refresh();
		System.out.println("Post construct on service called.");
		System.out.println(Arrays.asList(ctx.getBeanDefinitionNames()));
	}
	
	public ApplicationContext getContext() {
		return ctx;
	}


}

Spring Service Bean
src/main/java/com/test/HelloService.java

package com.test;

import org.springframework.stereotype.Service;

@Service
public class HelloService {
    String createHelloMessage(String name) {
        return "Hello " + name + "!";
    }
}

Rest Resource
src/main/java/com/test/HelloWorld.java

package com.test;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

/**
 * A simple REST service which is able to say hello to someone using HelloService Please take a look at the web.xml where JAX-RS
 * is enabled
 */

@Path("/")
public class HelloWorld {
    @Inject
    private ContextHolder contextHolder;
    private HelloService helloService;

    @PostConstruct
    void postConstruct() {
    	System.out.println("PostConstruct called.");
    	helloService = (HelloService) contextHolder.getContext().getBean("helloService");
    }
    
    @GET
    @Path("/json")
    @Produces({ "application/json" })
    public String getHelloWorldJSON() {
        return "{\"result\":\"" + helloService.createHelloMessage("World") + "\"}";
    }

    @GET
    @Path("/xml")
    @Produces({ "application/xml" })
    public String getHelloWorldXML() {
        return "<xml><result>" + helloService.createHelloMessage("World") + "</result></xml>";
    }

}
Full downloadable source for this page is available here.



Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 75 other followers

March 2017
S M T W T F S
« Mar    
 1234
567891011
12131415161718
19202122232425
262728293031  

Blog Stats

  • 813,721 hits