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.
- 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> - 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> - 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> - LimitOrderEntity.java (update)
import org.hibernate.annotations.Cache;import org.hibernate.annotations.CacheConcurrencyStrategy;@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)@Cacheable - MarketOrderEntity.java (update)
import org.hibernate.annotations.Cache;import org.hibernate.annotations.CacheConcurrencyStrategy;@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)@Cacheable - 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.
- 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> - 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" />
- 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.
- 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> - 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> - Update the configuration.
(cxf-java2ws-plugin)<configuration> <className>com.jboss.trading.ws.TradingServices</className> <genWsdl>true</genWsdl> </configuration> - 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> - Rename TradeManagerClient TradingServicesClient.
- 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); } } - Renamed TradeManagerClientIT TradingServicesClientIT.
- 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.
- 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










May 6, 2012 at 3:53 pm
Nice post.