JBoss Trading – Java EE 5 to Java EE 6 Migration Part II (JAX-WS 2.2 & JPA 2.0)

This post is the second in a series that covers the Java EE 5 to Java EE 6 migration of the JBoss Trading application (link).

This post covers the impact of CDI 1.0 and JAX-WS 2.2 on the packaging and the source code / configuration modifications required to implement it.

In addition, it covers JPA 2.0 and the source code / configuration modifications required to implement it.


Packaging

The Java EE 5 version of the JBoss Trading application (link) packages the application as an EAR containing a naked WAR and an EJB JAR.

The Java EE 6 version of the JBoss Trading application (link) packages the application as an EAR containing a WAR (that contains a JAR for the JAX-RS services and a JAR for the JAX-WS services) and an EJB JAR.

Source Code / Configuration

JBoss Trading Services

Hibernate Annotations (@Cache) is no longer required with JPA 2.0 (@Cacheable). The EJB no longer requires the JAX-WS annotations as there is a JAX-WS annotated POJO in the new JBoss Trading Web Services module.

  1. Remove the Hibernate Annotations dependency.
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>${hibernate-annotations}</version>
        <scope>provided</scope>
        <exclusions>
            <!-- jta 1.0.1.GA is a dependency of jboss-ejb-api -->
            <exclusion>
                <groupId>javax.transaction</groupId>
                <artifactId>jta</artifactId>
            </exclusion>
            <!-- xml-apis 2.9.1 is a dependency of jboss-ejb3-ext-api -->
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
  2. Exclude the JPA API dependency.
    <dependency>
        <groupId>org.jboss.ejb3</groupId>
        <artifactId>jboss-ejb3-ext-api</artifactId>
        <version>${jboss-ejb3-ext-api.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <artifactId>ejb3-persistence</artifactId>
                <groupId>org.hibernate</groupId>
            </exclusion>
        </exclusions>
    </dependency>
  3. Add the Java EE 6 (JPA) dependencies.
    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.0-api</artifactId>
        <version>1.0.1.Final</version>
        <scope>provided</scope>
    </dependency>
  4. LimitOrderEntity.java (update)
    import org.hibernate.annotations.Cache; 
    import org.hibernate.annotations.CacheConcurrencyStrategy;
    
    @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
    
    @Cacheable
  5. MarketOrderEntity.java (update)
    import org.hibernate.annotations.Cache; 
    import org.hibernate.annotations.CacheConcurrencyStrategy;
    
    @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
    
    @Cacheable
  6. TradeManagerBean.java (update)
    import javax.jws.WebService;
    
    @WebService

JBoss Trading Web Services

A new module for a JAX-WS annotated POJO. The EJB from the JBoss Trading Services module is injected into a JAX-WS annotated POJO using CDI with the business interface from the JBoss Trading API module and a qualifier.

  1. pom.xml (create)
    <?xml version="1.0"?>
    <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>
    
        <parent>
            <groupId>com.jboss.trading</groupId>
            <artifactId>trading-parent</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <relativePath>../trading-parent/pom.xml</relativePath>
        </parent>
        <artifactId>trading-ws</artifactId>
        <packaging>jar</packaging>
    
        <name>JBoss Trading Web Services</name>
    
        <build>
            <finalName>${project.artifactId}</finalName>
        </build>
    
        <dependencies>
            <dependency>
                <groupId>com.jboss.trading</groupId>
                <artifactId>trading-api</artifactId>
                <version>${project.version}</version>
                <scope>provided</scope>
            </dependency>
            <!-- CDI -->
            <dependency>
                <groupId>javax.enterprise</groupId>
                <artifactId>cdi-api</artifactId>
                <version>1.0-SP4</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </project>
  2. META-INF/beans.xml (create)
    <?xml version="1.0"?>
    <beans 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://jboss.org/schema/cdi/beans_1_0.xsd" />
  3. TradingServices.java (create)
    package com.jboss.trading.ws;
    
    import com.jboss.trading.api.TradeManager;
    import com.jboss.trading.api.exception.LimitOrderNotFoundException;
    import com.jboss.trading.api.exception.MarketOrderNotFoundException;
    import com.jboss.trading.api.exception.PlaceOrderException;
    import com.jboss.trading.api.model.LimitOrder;
    import com.jboss.trading.api.model.MarketOrder;
    import com.jboss.trading.api.model.TransactionType;
    import java.util.List;
    import javax.inject.Inject;
    import javax.inject.Named;
    import javax.jws.WebService;
    
    @WebService
    public class TradingServices {
    
        @Inject 
        @Named("TradeManagerBean")
        TradeManager tradeManager;
    
        public void cancelLimitOrder(Integer limitOrderId)
                throws LimitOrderNotFoundException {
    
            tradeManager.cancelLimitOrder(limitOrderId);
        }
        public void cancelMarketOrder(Integer marketOrderId)
                throws MarketOrderNotFoundException {
    
            tradeManager.cancelMarketOrder(marketOrderId);
        }
        public void placeLimitOrder(
                Integer stockHolderId, TransactionType transactionType,
                Integer quantity, String stockSymbol, Float price) 
                throws PlaceOrderException {
    
            tradeManager.placeLimitOrder(
                    stockHolderId, transactionType, quantity, 
                    stockSymbol, price);
        }
        public void placeMarketOrder(
                Integer stockHolderId, TransactionType transactionType,
                Integer quantity, String stockSymbol) {
    
            tradeManager.placeMarketOrder(
                    stockHolderId, transactionType, quantity,
                    stockSymbol);
        }
    
        public LimitOrder viewLimitOrder(Integer limitOrderId)
                throws LimitOrderNotFoundException {
    
            return tradeManager.viewLimitOrder(limitOrderId);
        }
    
        public MarketOrder viewMarketOrder(Integer marketOrderId)
                throws MarketOrderNotFoundException {
    
            return tradeManager.viewMarketOrder(marketOrderId);
        }
    
        public List<LimitOrder> viewStockHolderLimitOrders(
                Integer stockHolderId, Integer numberLimitOrders) {
    
            return tradeManager.viewStockHolderLimitOrders(
                    stockHolderId, numberLimitOrders);
        }
    
        public List<MarketOrder> viewStockHolderMarketOrders(
                Integer stockHolderId, Integer numberMarketOrders) {
    
            return tradeManager.viewStockHolderMarketOrders(
                    stockHolderId, numberMarketOrders);
        }
    }

JBoss Trading WS Client

The web service client is generated from the JAX-WS annotated POJO from the new JBoss Trading Web Services module instead of the EJB from the JBoss Trading Services module.

For clarification, the client is renamed to TradingServicesClient and the integration test is renamed TradingServicesClientIT.

  1. Remove the JBoss Trading Services dependencies.
    (cxf-java2ws-plugin)

    <dependency>
        <groupId>com.jboss.trading</groupId>
        <artifactId>trading-services</artifactId>
        <version>${project.version}</version>
        <type>ejb</type>
    </dependency>
    <dependency>
        <groupId>org.jboss.ejb3</groupId>
        <artifactId>jboss-ejb3-ext-api</artifactId>
        <version>${jboss-ejb3-ext-api.version}</version>
    </dependency>
  2. Add the JBoss Trading Web Services dependency.
    (cxf-java2ws-plugin)

    <dependency>
        <groupId>com.jboss.trading</groupId>
        <artifactId>trading-ws</artifactId>
        <version>${project.version}</version>
    </dependency>
  3. Update the configuration.
    (cxf-java2ws-plugin)

    <configuration>
        <className>com.jboss.trading.ws.TradingServices</className>
        <genWsdl>true</genWsdl>
    </configuration>
  4. Update the configuration.
    (cxf-codegen-plugin)

    <configuration>
        <wsdlOptions>
            <wsdlOption>
                <wsdl>${project.build.directory}/generated/wsdl/TradingServices.wsdl</wsdl>
                <extraargs>
                    <extraarg>-p</extraarg>
                    <extraarg>com.jboss.trading.ws.client.model</extraarg>
                </extraargs>
            </wsdlOption>
        </wsdlOptions>
    </configuration>
  5. Rename TradeManagerClient TradingServicesClient.
  6. TradingServicesClient.java (update)
    package com.jboss.trading.ws.client;
    
    import com.jboss.trading.ws.client.model.*;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.List;
    
    public class TradingServicesClient {
    
        TradingServices tradingServices;
    
        public TradingServicesClient(TradingServices tradingServices) {
    
            this.tradingServices = tradingServices;
        }
    
        public static TradingServicesClient getInstance(String urlStr) 
                throws MalformedURLException {
    
            URL url = new URL(urlStr);
    
            TradingServicesService service = 
                            new TradingServicesService(url);
    
            TradingServices tradingServices = 
                            service.getTradingServicesPort();
    
            TradingServicesClient client = 
                            new TradingServicesClient(tradingServices);
    
            return client;
        }
    
        public void cancelLimitOrder(Integer limitOrderId) 
                throws LimitOrderNotFoundException_Exception {
    
            tradingServices.cancelLimitOrder(limitOrderId);
        }
    
        public void cancelMarketOrder(Integer marketOrderId) 
                throws MarketOrderNotFoundException_Exception {
    
            tradingServices.cancelMarketOrder(marketOrderId);
        }
    
        public void placeLimitOrder(
                Integer stockHolderId, TransactionType transactionType,
                Integer quantity, String stockSymbol, Float price) 
                throws PlaceOrderException_Exception {
    
            tradingServices.placeLimitOrder(
                            stockHolderId, transactionType,
                            quantity, stockSymbol, price);
        }
    
        public void placeMarketOrder(
                Integer stockHolderId, TransactionType transactionType,
                Integer quantity, String stockSymbol) {
    
            tradingServices.placeMarketOrder(
                            stockHolderId, transactionType,
                            quantity, stockSymbol);
        }
    
        public LimitOrder viewLimitOrder(Integer limitOrderId) 
                throws LimitOrderNotFoundException_Exception {
    
            return tradingServices.viewLimitOrder(limitOrderId);
        }
        public MarketOrder viewMarketOrder(Integer marketOrderId) 
                throws MarketOrderNotFoundException_Exception {
    
            return tradingServices.viewMarketOrder(marketOrderId);
        }
    
        public List<LimitOrder> viewStockHolderLimitOrders(
                Integer stockHolderId, Integer numberLimitOrders) {
    
            return tradingServices.viewStockHolderLimitOrders(
                            stockHolderId, numberLimitOrders);
        }
    
        public List<MarketOrder> viewStockHolderMarketOrders(
                Integer stockHolderId, Integer numberMarketOrders) {
    
            return tradingServices.viewStockHolderMarketOrders(
                            stockHolderId, numberMarketOrders);
        }
    }
  7. Renamed TradeManagerClientIT TradingServicesClientIT.
  8. TradingServicesClientIT.java (update)
    package com.jboss.trading.ws.client.test;
    
    import com.jboss.trading.test.TestConfig;
    import com.jboss.trading.ws.client.TradingServicesClient;
    import com.jboss.trading.ws.client.model.*;
    import java.net.MalformedURLException;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;
    import org.junit.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class TradingServicesClientIT {
    
        private static final Logger LOGGER = 
                LoggerFactory.getLogger(TradingServicesClientIT.class);
    
        private TestConfig testConfig;
    
        private ClientTestConfig clientTestConfig;
    
        private TradingServicesClient tradingServicesClient;
    
        public TradingServicesClientIT() {
    
            testConfig = TestConfig.getInstance();
    
            clientTestConfig = ClientTestConfig.getInstance();
    
            String wsdlUrl = clientTestConfig.getWsdlUrl();
    
            try {
    
                tradingServicesClient = 
                        TradingServicesClient.getInstance(wsdlUrl);
            } 
            catch (MalformedURLException ex) {
    
                LOGGER.error(ex.getMessage(), ex);
            }
        }
    
        @BeforeClass
        public static void setUpClass() throws Exception {
        }
    
        @AfterClass
        public static void tearDownClass() throws Exception {
        }
    
        @Before
        public void setUp() {
        }
    
        @After
        public void tearDown() {
        }
    
        @Test
        public void testPlaceBuyLimitOrder() throws Exception {
    
            try {
    
                tradingServicesClient.placeLimitOrder(
                        testConfig.getStockHolderId(),
                        TransactionType.BUY, testConfig.getQuantity(),
                        testConfig.getStockSymbol(), testConfig.getPrice());
            } 
            catch (PlaceOrderException_Exception ex) {
    
                Assert.fail(ex.getMessage());
            }
        }
    
        @Test
        public void testPlaceBuyMarketOrder() throws Exception {
    
            tradingServicesClient.placeMarketOrder(
                    testConfig.getStockHolderId(), TransactionType.BUY, 
                    testConfig.getQuantity(), testConfig.getStockSymbol());
        }
    
        @Test
        public void testPlaceSellLimitOrder() throws Exception {
    
            try {
    
                tradingServicesClient.placeLimitOrder(
                        testConfig.getStockHolderId(), TransactionType.SELL, 
                        testConfig.getQuantity(), testConfig.getStockSymbol(), 
                        testConfig.getPrice());
            } 
            catch (PlaceOrderException_Exception ex) {
    
                Assert.fail(ex.getMessage());
            }
        }
    
        @Test
        public void testPlaceSellMarketOrder() throws Exception {
    
            tradingServicesClient.placeMarketOrder(
                    testConfig.getStockHolderId(), TransactionType.SELL, 
                    testConfig.getQuantity(), testConfig.getStockSymbol());
        }
    
        @Test
        public void testViewLimitOrder() throws Exception {
    
            AtomicInteger limitOrderIdCounter = 
                    testConfig.getLimitOrderIdCounter();
    
            LimitOrder limitOrder = 
                    tradingServicesClient.viewLimitOrder(
                            limitOrderIdCounter.getAndIncrement());
    
            Assert.assertNotNull(limitOrder);
        }
    
        @Test
        public void testViewMarketOrder() throws Exception {
    
            AtomicInteger marketOrderIdCounter = 
                    testConfig.getMarketOrderIdCounter();
    
            MarketOrder marketOrder = 
                    tradingServicesClient.viewMarketOrder(
                            marketOrderIdCounter.getAndIncrement());
    
            Assert.assertNotNull(marketOrder);
        }
    
        @Test
        public void testViewStockHolderLimitOrders() throws Exception {
    
            List<LimitOrder> limitOrders =
                    tradingServicesClient.viewStockHolderLimitOrders(
                            testConfig.getStockHolderId(), 
                            testConfig.getMaxLimitOrderResults());
    
            Assert.assertNotNull(limitOrders);
            Assert.assertFalse(limitOrders.isEmpty());
        }
    
        @Test
        public void testViewStockHolderMarketOrders() throws Exception {
    
            List<MarketOrder> marketOrders =
                    tradingServicesClient.viewStockHolderMarketOrders(
                            testConfig.getStockHolderId(), 
                            testConfig.getMaxMarketOrderResults());
    
            Assert.assertNotNull(marketOrders);
            Assert.assertFalse(marketOrders.isEmpty());
        }
    
        @Test
        public void testCancelLimitOrder() throws Exception {
    
            AtomicInteger limitOrderIdCounter = 
                    testConfig.getLimitOrderIdCounter();
    
            try {
    
                tradingServicesClient.cancelLimitOrder(
                        limitOrderIdCounter.decrementAndGet());
            } 
            catch (LimitOrderNotFoundException_Exception ex) {
    
                Assert.fail(ex.getMessage());
            }
        }
    
        @Test
        public void testCancelMarketOrder() throws Exception {
    
            AtomicInteger marketOrderIdCounter = 
                    testConfig.getMarketOrderIdCounter();
    
            try {
    
                tradingServicesClient.cancelMarketOrder(
                        marketOrderIdCounter.decrementAndGet());
            } 
            catch (MarketOrderNotFoundException_Exception ex) {
    
                Assert.fail(ex.getMessage());
            }
        }
    
        @Test
        public void testcancelLimitOrderFailure() throws Exception {
    
            AtomicInteger limitOrderIdCounter = 
                    testConfig.getLimitOrderIdCounter();
    
            int limitOrderId = limitOrderIdCounter.getAndIncrement();
    
            try {
    
                tradingServicesClient.cancelLimitOrder(limitOrderId);
    
                Assert.fail();
            } 
            catch (LimitOrderNotFoundException_Exception ex) {
    
                Assert.assertEquals(
                        String.format(
                                testConfig.getCancelLimitOrderErrorMsgPrefix(), 
                                limitOrderId), ex.getMessage());
            }
        }
    
        @Test
        public void testcancelMarketOrderFailure() throws Exception {
    
            AtomicInteger marketOrderCounter = 
                    testConfig.getMarketOrderIdCounter();
    
            int marketOrderId = marketOrderCounter.getAndIncrement();
    
            try {
    
                tradingServicesClient.cancelMarketOrder(marketOrderId);
    
                Assert.fail();
            } 
            catch (MarketOrderNotFoundException_Exception ex) {
    
                Assert.assertEquals(
                        String.format(
                                testConfig.getCancelMarketOrderErrorMsgPrefix(), 
                                marketOrderId), ex.getMessage());
            }
        }
    }

JBoss Trading REST

The web services are exposed by the WAR instead of the EJB JAR.

  1. Add the JBoss Trading Web Services dependency.
    <dependency>
        <groupId>com.jboss.trading</groupId>
        <artifactId>trading-ws</artifactId>
        <version>${project.version}</version>
    </dependency>

Build

mvn clean package -Plocalhost-remote -DskipTests

JBoss Trading – Java EE 5 to Java EE 6 Migration

  • Part I – CDI 1.0 & JAX-RS 1.1 (link)
  • Part II – JPA 2.0 & JAX-WS 2.2
  • Part III – Structure & Packaging (link)
  • Part IV – Deployment & Testing (link)
  • Part V – Clean Up (link)
, , , , ,

About Shane K Johnson

Technical Marketing Manager, Red Hat Inc.

View all posts by Shane K Johnson

One Comment on “JBoss Trading – Java EE 5 to Java EE 6 Migration Part II (JAX-WS 2.2 & JPA 2.0)”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 105 other followers

%d bloggers like this: