Monday, July 28, 2014

EJB 3.1 and JTA

Configuring JTA and EJB 3.1 with JBOSS 7.1.1 final

  Please see the post on how to configure the different JTA data sources on JBOSS7


Bean managed JTA transactions

EJB 3.1 and JPA

Some fundamentals tips to start with JPA and ejb 3.1 with JBOSS 7.1.1 final

Add the data sources to the JBOSS_HOME/standalone/configuration/standalone.xml

<subsystem xmlns="urn:jboss:domain:datasources:1.0">
            <datasources>
                <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
                    <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url>
                    <driver>h2</driver>
                    <security>
                        <user-name>sa</user-name>
                        <password>sa</password>
                    </security>
                </datasource>
                <datasource jndi-name="java:jboss/datasources/MySqlDS" pool-name="MySqlDS" enabled="true" use-java-context="true">
                    <connection-url>jdbc:mysql://localhost:3306/nit_test</connection-url>
                    <driver>mysqlDriver</driver>
                    <security>
                        <user-name>root</user-name>
                        <password>root</password>
                    </security>
                </datasource>
                <drivers>
                    <driver name="h2" module="com.h2database.h2">
                        <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
                    </driver>
                    <driver name="mysqlDriver" 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>
       

Choose the right JDBC driver.
Some drivers do not support two phase commit. Hence a choice must be made for the right driver.
For example MySQL has DataSource classes like com.mysql.jdbc.jdbc2.optional.MysqlDataSource and com.mysql.jdbc.jdbc2.optional.MysqlXADataSource. Please chooce them wisely. For a list of JDBC Drivers, please refer to: http://docs.oracle.com/cd/E19798-01/821-1751/ghhvc/index.html - See more at: http://www.developerscrappad.com/435/java/java-ee/ejb-3-x-jpa-bean-managed-transaction-with-javax-ejb-usertransaction/#sthash.OPPE5fx7.dpuf
For example mysql datasources classes like com.mysql.jdbc.jdbc2.optional.MysqlDataSource
and com.mysql.jdbc.jdbc2.optional.MysqlXADataSource.
Check oracle documentation JDBC data sources

Add Connection jars to JBOSS modules

Create a directory in JBOSS_HOME/modules/com/mysql/main ( if not already present )
Add mysql-connector-java-x.x.x.jar to this directory.

Edit the module.xmla shown below:

<module xmlns="urn:jboss:module:1.1" name="com.mysql">
    <resources>
        <resource-root path="mysql-connector-java-5.1.31-bin.jar"/>
    </resources>

    <dependencies>
      <module name="javax.api"/>
    </dependencies>
</module>

Add persistence.xml to the EJB project

Add persistence.xml to the META-INF of the project.

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
        <persistence-unit name="Counter">
               <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>java:jboss/datasources/MySqlDS</jta-data-source>
      <class>com.goraksh.test.JPACounterEntity</class>
      <exclude-unlisted-classes>true</exclude-unlisted-classes>
    
        </persistence-unit>
</persistence>

Here is the jta-data-source is the JNDI name of the mysql data source configured in the standalone.xml

Using managed JTA with EJB 3.1 with JBOSS 7.1.1

Managed JTA transactions

For example MySQL has DataSource classes like com.mysql.jdbc.jdbc2.optional.MysqlDataSource and com.mysql.jdbc.jdbc2.optional.MysqlXADataSource. Please chooce them wisely. For a list of JDBC Drivers, please refer to: http://docs.oracle.com/cd/E19798-01/821-1751/ghhvc/index.html - See more at: http://www.developerscrappad.com/435/java/java-ee/ejb-3-x-jpa-bean-managed-transaction-with-javax-ejb-usertransaction/#sthash.OPPE5fx7.dpuf

Wednesday, June 25, 2014

Basics of Spring MVC with JBoss 7.1

Using JBoss 7.1.1 as the Application server.

Following files of concern for basic debugging

1. \jboss\jboss-as-7.1.1.Final\standalone\configuration\standalone.xml -->  This files contains the EE configurations files.

Use  deployment scanner to assign the different war,ear locations to be loaded for Jboss deployment.


Like the below contents has two deployment scanner for two different web apps
a.) One app1*.war resides in the standalone\deployments dir of JBoss home
b.) Another app2*.war resides in the eclipse runtime jboss tools dir. This dir is automatically chosen by eclipse when deploying an app on JBoss server.
To configure a Jboss sever with eclipse ( kepler ) : Add the url :
 http://download.jboss.org/jbosstools/updates/stable/kepler/ to eclipse help-->New software-->works with

Then in eclipse preferences-->server add the Jboss7.1.* Runtime.
Then eclipse ''servers'' view perspective add the desired web app to the server


<subsystem xmlns="urn:jboss:domain:deployment-scanner:1.1">
            <deployment-scanner name="customscaner" path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" deployment-timeout="120"/>
            <deployment-scanner name="jbosstoolsscanner1" path="E:\workspace\.metadata\.plugins\org.jboss.ide.eclipse.as.core\JBoss_7.1_Runtime_Server1403588064851\deploy" scan-interval="5000" deployment-timeout="120"/>
        </subsystem>

Use domain logging to configure the different log levels and the log files. 

The below is the snippet from standalone.xml

<subsystem xmlns="urn:jboss:domain:logging:1.1">
            <console-handler name="CONSOLE">
                <level name="INFO"/>
                <formatter>
......
........
</subsystem>

Springs Context and Web Context Configurations


Sample web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/spring-context.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/user/*</url-pattern>
</servlet-mapping>
</web-app>


contextConfigLocation parameter values gives the path of the spring context file to be loaded by the dispatcher servlet.

spring-context.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.goraksh" />
<mvc:annotation-driven />
       <mvc:default-servlet-handler/>
<bean id="userDAO" class="com.goraksh.UserDAO">
        <property name="dataSrc" ref="userDataSrc"/>
    </bean>
    
<bean id="userDataSrc" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!--  max active connections by default is 8 -->
        <property name="driverClassName" value="${jdbc.security.driverClassName}"/>
        <property name="url" value="${jdbc.security.url}"/>
        <property name="username" value="${jdbc.security.username}"/>
        <property name="password" value="${jdbc.security.password}"/>
    </bean>
<bean id="securityTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSrc" ref="userDataSrc"/>
</bean>
<context:property-placeholder location="classpath:jdbc.properties"/>
</beans>

Certains subtleties for new bees
Dispatcher servlet can be used only for the servlet and jsp files residing in the WEB-INF directory.
For the static resources like static htmls, css, js, etc. Dispatcher servlet mapping will not work.

So if I change from Url pattern to <url-pattern>/*</url-pattern> instead of <url-pattern>/user/*</url-pattern>

and removes the lines <mvc:default-servlet-handler/> from the spring-context.xml then an static html file, say hello.html, residing directly inside the web app context but outside the WEB-INF directory will not be loaded. The logs will report the the desired Dispatcher servlet could not find the mapping for ..../hello.html. !!!

To get away with this problem, there are multiple approaches

1. Give a more precise URI for View classes to handled by Dispatcher servlet. Hence the need for /user/*. So all URIs contains ''user'' alone will be handled by Dispatcher servlet.

2. To handler the static components, which cannot be loaded by Dispatcher, I have used
<mvc:default-servlet-handler/> in the spring-context.xml

3. This is an an alternate to step 2
Instead of step#2 , you can also use <mvc:resources mapping="/*" location="/" /> in the spring-context.xml. <mvc:resources mapping="/*" location="/" /> will replace the line <mvc:default-servlet-handler/>. This step is workable only for spring version 3.0.4 and above.

See the Stack Over Discussion