<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1780439233174741141</id><updated>2012-02-16T12:55:10.728+02:00</updated><category term='software quality'/><category term='jquery'/><category term='jms. jta'/><category term='activemq'/><category term='fusion middleware'/><category term='integration'/><category term='sdlc'/><category term='wiquery'/><category term='wicket'/><category term='jpa'/><category term='jetty'/><category term='spring'/><category term='jdbc hibernate'/><category term='atomikos'/><category term='middleware'/><category term='vodafone'/><category term='ofm'/><title type='text'>pay no attention to the man behind the curtain</title><subtitle type='html'>this blog is a transcript of the tastes I've learned while coding my own dog food...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-2266989315575397504</id><published>2011-06-26T16:31:00.000+03:00</published><updated>2011-06-26T16:31:23.633+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='activemq'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='jms. jta'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='atomikos'/><title type='text'>Integrating: Jetty, Spring, AspectJ, Wicket, Hibernate, MySQL, ActiveMQ and Atomikos (web archive scope)</title><content type='html'>&lt;h1&gt;Overview&lt;/h1&gt;&lt;br /&gt;The Spring framework has long provided an attractive alternative to J2EE application servers (especially prior to the arrival of JavaEE 6). Development teams often opted to go for a setup that uses Spring to manage the application context, coupled with a plain Servlet/JSP container and a good ORM solution.&lt;br /&gt;&lt;br /&gt;Indeed, the "Jetty/Tomcat + Spring + Hibernate" stack has served many projects. As growth and complexity kicks in, things like JMS and (not long after that) XA transactions, start becoming a necessity.&lt;br /&gt;&lt;br /&gt;It is at that point that teams start discussing the use of an application server, in order to gain a "certified" stack that combines all of the above (and more) facilities. However, some teams want to keep on using the "roll your own" path, by adding these aspects into the mix.&lt;br /&gt;&lt;br /&gt;In this entry I will describe a setup that combines the most common JEE APIs using a custom assembly of components. The setup comprises of:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Jetty 7.3.1 (Servlet/JSP)&lt;/li&gt;&lt;li&gt;Spring 3.0.5 (CDI)&lt;/li&gt;&lt;li&gt;AspectJ 1.6.10 (because it is cool)&lt;/li&gt;&lt;li&gt;Atomikos 3.7.0 (JTA with XA support)&lt;/li&gt;&lt;li&gt;Hibernate 3.6.0 (JPA)&lt;/li&gt;&lt;li&gt;ActiveMQ 5.5.0 (JMS)&lt;/li&gt;&lt;li&gt;MySQL (JDBC, using driver 5.1.15)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Note that all of the above are integrated at the Web Archive level (i.e. the libraries are all included in WEB-INF/lib with nothing placed in the JVM classpath). This is because I often choose to "embed" Jetty when working in this mode, using my own custom launcher.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;The basics: a Spring-enabled WAR, with Wicket managing the presentation&lt;/h1&gt;&lt;br /&gt;Since we will use Spring to inject all of the resources (JTA, JDBC connections, JPA Persistence Units, JMS, ...), the first step is to create a Spring-enabled WAR. In this step, we will also integrate Apache Wicket to take over page generation (sorry, but I have long hated JSF and JSP with a passion, so these are the first thing I want to get rid of.&lt;br /&gt;&lt;br /&gt;So, we start by updating our web.xml as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;&lt;br /&gt;&lt;web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&lt;br /&gt; xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&lt;br /&gt; version="2.5"&gt;&lt;br /&gt;&lt;br /&gt; &lt;display-name&gt;My own near-JEE stack&lt;/display-name&gt;&lt;br /&gt;&lt;br /&gt; &lt;context-param&gt;&lt;br /&gt;  &lt;description&gt;Wicket mode (development/deployment)&lt;/description&gt;&lt;br /&gt;  &lt;param-name&gt;wicket.configuration&lt;/param-name&gt;&lt;br /&gt;  &lt;!-- When you build for production, remember to change this --&gt;&lt;br /&gt;  &lt;!-- Maven can help you with this! :-) --&gt;&lt;br /&gt;  &lt;param-value&gt;development&lt;/param-value&gt;&lt;br /&gt; &lt;/context-param&gt;&lt;br /&gt;&lt;br /&gt; &lt;filter&gt;&lt;br /&gt;  &lt;filter-name&gt;my.app.filter.wicket&lt;/filter-name&gt;&lt;br /&gt;  &lt;filter-class&gt;org.apache.wicket.protocol.http.WicketFilter&lt;/filter-class&gt;&lt;br /&gt;  &lt;init-param&gt;&lt;br /&gt;   &lt;param-name&gt;applicationClassName&lt;/param-name&gt;   &lt;param-value&gt;my.Application&lt;/param-value&gt;  &lt;/init-param&gt;&lt;br /&gt; &lt;/filter&gt;&lt;br /&gt; &lt;filter-mapping&gt;&lt;br /&gt;  &lt;!-- Wicket for everything! --&gt;&lt;br /&gt;  &lt;filter-name&gt;my.app.filter.wicket&lt;/filter-name&gt;&lt;br /&gt;  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;&lt;br /&gt; &lt;/filter-mapping&gt;&lt;br /&gt;&lt;br /&gt; &lt;context-param&gt;&lt;br /&gt;  &lt;description&gt;Main Spring context configuration file&lt;/description&gt;&lt;br /&gt;  &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;  &lt;!-- Spring context is built starting with this file --&gt;&lt;br /&gt;  &lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;&lt;br /&gt; &lt;/context-param&gt;&lt;br /&gt;&lt;br /&gt; &lt;listener&gt;&lt;br /&gt;  &lt;!-- This Spring listener will kick in on application startup --&gt;&lt;br /&gt;  &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;&lt;br /&gt; &lt;/listener&gt;&lt;br /&gt;&lt;br /&gt; &lt;login-config&gt;&lt;br /&gt;  &lt;auth-method&gt;BASIC&lt;/auth-method&gt;&lt;br /&gt; &lt;/login-config&gt;&lt;br /&gt;&lt;/web-app&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is all that is needed for web.xml. The rest of the magic lies totally within Spring's configuration file (&lt;tt&gt;/WEB-INF/applicationContext.xml&lt;/tt&gt;).&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;br /&gt;&lt;beans xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"&lt;br /&gt; xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jms="http://www.springframework.org/schema/jms"&lt;br /&gt; xsi:schemaLocation="http://www.springframework.org/schema/beans &lt;br /&gt;           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;           http://www.springframework.org/schema/context&lt;br /&gt;           http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;           http://www.springframework.org/schema/tx&lt;br /&gt;           http://www.springframework.org/schema/tx/spring-tx-3.0.xsd&lt;br /&gt;           http://www.springframework.org/schema/jms&lt;br /&gt;           http://www.springframework.org/schema/jms/spring-jms-3.0.xsd"&gt;&lt;br /&gt;&lt;br /&gt; &lt;!-- Activate compile-time-woven objects --&gt;&lt;br /&gt; &lt;context:spring-configured&gt;&lt;/context:spring-configured&gt;&lt;br /&gt;&lt;br /&gt; &lt;!-- Define transaction manager context --&gt;&lt;br /&gt; &lt;import resource="classpath:META-INF/spring/tx-services.xml"&gt;&lt;/import&gt;&lt;br /&gt;&lt;br /&gt; &lt;!-- Define JMS messaging context --&gt;&lt;br /&gt; &lt;import resource="classpath:META-INF/spring/jms-services.xml"&gt;&lt;/import&gt;&lt;br /&gt;&lt;br /&gt; &lt;!-- Define database persistence context --&gt;&lt;br /&gt; &lt;import resource="classpath:META-INF/spring/db-services.xml"&gt;&lt;/import&gt;&lt;br /&gt;&lt;br /&gt;&lt;/beans&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that the references to &lt;tt&gt;META-INF/spring/...&lt;/tt&gt; are presented in the following sections.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Adding the Atomikos JTA implementation&lt;/h1&gt;&lt;br /&gt;The next step is to create the &lt;tt&gt;META-INF/spring/tx-services.xml&lt;/tt&gt; where we instantiate the Atomikos transaction manager and bind it as our JTA implementation. Note that this is where we need to explaing to Spring that we are using AspectJ and therefore the @Transactional annotation must be handled via @Configurable at the class implementation level.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;br /&gt;&lt;beans&lt;br /&gt;    xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt;    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;    xmlns:tx="http://www.springframework.org/schema/tx"&lt;br /&gt;    xmlns:aop="http://www.springframework.org/schema/aop"&lt;br /&gt;    xsi:schemaLocation="http://www.springframework.org/schema/beans &lt;br /&gt;           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;           http://www.springframework.org/schema/tx&lt;br /&gt;           http://www.springframework.org/schema/tx/spring-tx-3.0.xsd&lt;br /&gt;           http://www.springframework.org/schema/aop&lt;br /&gt;           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;&lt;br /&gt;&lt;br /&gt; &lt;!-- Atomikos transaction manager implementation --&gt;&lt;br /&gt; &lt;bean id="atomikosTransactionManager"&lt;br /&gt;   class="com.atomikos.icatch.jta.UserTransactionManager"&lt;br /&gt;   init-method="init" destroy-method="close"&gt;&lt;br /&gt;  &lt;!-- when close is called, should we force transactions to terminate or not? --&gt;&lt;br /&gt;  &lt;property name="forceShutdown" value="false"/&gt;&lt;br /&gt; &lt;/bean&gt;&lt;br /&gt; &lt;!-- Atomikos transaction implementation --&gt;&lt;br /&gt; &lt;bean id="atomikosUserTransaction"&lt;br /&gt;   class="com.atomikos.icatch.jta.UserTransactionImp"&gt;&lt;br /&gt;  &lt;property name="transactionTimeout" value="10"/&gt;&lt;br /&gt; &lt;/bean&gt;&lt;br /&gt;&lt;br /&gt; &lt;!-- Create JTA transaction manager using Atomikos --&gt;&lt;br /&gt; &lt;bean id="transactionManager"&lt;br /&gt;   class="org.springframework.transaction.jta.JtaTransactionManager"&gt;&lt;br /&gt;  &lt;property name="transactionManager" ref ="atomikosTransactionManager" /&gt;&lt;br /&gt;  &lt;property name="userTransaction" ref="atomikosUserTransaction" /&gt;&lt;br /&gt; &lt;/bean&gt;&lt;br /&gt;&lt;br /&gt;    &lt;bean id="annotationTransactionAspect" factory-method="aspectOf" &lt;br /&gt;        class="org.springframework.transaction.aspectj.AnnotationTransactionAspect"&gt;&lt;br /&gt;        &lt;property name="transactionManager" ref="transactionManager"&gt;&lt;/property&gt;&lt;br /&gt;    &lt;/bean&gt;&lt;br /&gt;&lt;br /&gt;    &lt;!-- Use AspectJ for @Transactional, detecting it on CLASS (not interface) --&gt;&lt;br /&gt;    &lt;tx:annotation-driven transaction-manager="transactionManager" &lt;br /&gt;     mode="aspectj" proxy-target-class="true" /&gt;&lt;br /&gt;&lt;/beans&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h1&gt;Integrating ActiveMQ as a JMS provider that uses Atomikos for transaction management&lt;/h1&gt;&lt;br /&gt;The next step is to create the &lt;tt&gt;META-INF/spring/jms-services.xml&lt;/tt&gt; where we define the ActiveMQ broker and tell it to interact with Atomikos for participating in transactions...&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;br /&gt;&lt;beans&lt;br /&gt;    xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt;    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;    xmlns:context="http://www.springframework.org/schema/context"&lt;br /&gt;    xmlns:jms="http://www.springframework.org/schema/jms"&lt;br /&gt; xmlns:broker="http://activemq.apache.org/schema/core"&lt;br /&gt;    xsi:schemaLocation="http://www.springframework.org/schema/beans &lt;br /&gt;           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;           http://www.springframework.org/schema/context&lt;br /&gt;           http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;           http://www.springframework.org/schema/jms&lt;br /&gt;           http://www.springframework.org/schema/jms/spring-jms-3.0.xsd&lt;br /&gt;           http://activemq.apache.org/schema/core&lt;br /&gt;           http://activemq.apache.org/schema/core/activemq-core-5.5.0.xsd"&gt;&lt;br /&gt;&lt;br /&gt; &lt;!-- XA-capable connector for ActiveMQ broker --&gt;&lt;br /&gt; &lt;bean id="amqXaConnectionFactory"&lt;br /&gt;   class="org.apache.activemq.ActiveMQXAConnectionFactory"&gt;&lt;br /&gt;  &lt;property name="brokerURL" value="tcp://localhost:61616"/&gt;&lt;br /&gt;  &lt;property name="prefetchPolicy"&gt;&lt;br /&gt;         &lt;bean class="org.apache.activemq.ActiveMQPrefetchPolicy"&gt;&lt;br /&gt;    &lt;property name="queuePrefetch" value="1"/&gt;&lt;br /&gt;   &lt;/bean&gt;&lt;br /&gt;  &lt;/property&gt;&lt;br /&gt;  &lt;property name="redeliveryPolicy"&gt;&lt;br /&gt;   &lt;bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy"&gt;&lt;br /&gt;    &lt;property name="maximumRedeliveries" value="0"&gt;&lt;/property&gt;&lt;br /&gt;    &lt;property name="initialRedeliveryDelay" value="1000" &gt;&lt;/property&gt;&lt;br /&gt;    &lt;property name="redeliveryDelay" value="2000"&gt;&lt;/property&gt;&lt;br /&gt;    &lt;property name="useExponentialBackOff" value="true"&gt;&lt;/property&gt;&lt;br /&gt;    &lt;property name="backOffMultiplier" value="2"&gt;&lt;/property&gt;&lt;br /&gt;    &lt;property name="maximumRedeliveryDelay" value="32000"&gt;&lt;/property&gt;&lt;br /&gt;   &lt;/bean&gt;&lt;br /&gt;  &lt;/property&gt;&lt;br /&gt; &lt;/bean&gt;&lt;br /&gt;&lt;br /&gt; &lt;!-- Atomikos-wrapped XA connection factory for JMS broker --&gt;&lt;br /&gt; &lt;bean id="connectionFactory"&lt;br /&gt;   class="com.atomikos.jms.AtomikosConnectionFactoryBean"&gt;&lt;br /&gt;  &lt;property name="uniqueResourceName" value="amq1"&gt;&lt;/property&gt;&lt;br /&gt;  &lt;property name="xaConnectionFactory" ref="amqXaConnectionFactory"&gt;&lt;/property&gt;&lt;br /&gt;  &lt;property name="maxPoolSize" value="10"&gt;&lt;/property&gt;&lt;br /&gt; &lt;/bean&gt;&lt;br /&gt;&lt;br /&gt; &lt;broker:broker id="my-broker"&lt;br /&gt;   useJmx="true" persistent="true" brokerName="localhost"&gt;&lt;br /&gt;  &lt;broker:persistenceAdapter&gt;&lt;br /&gt;   &lt;broker:amqPersistenceAdapter directory="/path/to/ActiveMQ/file/store" maxFileLength="4mb" /&gt;&lt;br /&gt;  &lt;/broker:persistenceAdapter&gt;&lt;br /&gt;  &lt;broker:transportConnectors&gt;&lt;br /&gt;   &lt;broker:transportConnector uri="tcp://localhost:61616"&gt;&lt;/broker:transportConnector&gt;&lt;br /&gt;  &lt;/broker:transportConnectors&gt;&lt;br /&gt; &lt;/broker:broker&gt;&lt;br /&gt;&lt;br /&gt; &lt;broker:queue id="registrationQueue" physicalName="registrationQueue"&gt;&lt;/broker:queue&gt;&lt;br /&gt;&lt;br /&gt; &lt;bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"&gt;&lt;br /&gt;  &lt;property name="connectionFactory" ref="connectionFactory"&gt;&lt;/property&gt;&lt;br /&gt;  &lt;property name="sessionTransacted" value="true"&gt;&lt;/property&gt;&lt;br /&gt; &lt;/bean&gt;&lt;br /&gt;&lt;br /&gt; &lt;bean id="jmsProcessor"&lt;br /&gt;  class="my.application.jms.ClassImplementingMessageListener"&gt;&lt;/bean&gt;&lt;br /&gt;&lt;br /&gt; &lt;jms:listener-container&lt;br /&gt;   connection-factory="connectionFactory"&lt;br /&gt;   transaction-manager="transactionManager"&lt;br /&gt;   acknowledge="transacted"&lt;br /&gt;   concurrency="5"&gt;&lt;br /&gt;  &lt;jms:listener destination="registrationQueue" ref="registrationProcessor"&gt;&lt;/jms:listener&gt;&lt;br /&gt; &lt;/jms:listener-container&gt;&lt;br /&gt;&lt;/beans&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h1&gt;Integrating Hibernate as a JPA provider that uses Atomikos for transaction management&lt;/h1&gt;&lt;br /&gt;Last but not least, the &lt;tt&gt;META-INF/spring/db-services.xml&lt;/tt&gt; will add Hibernate to the mix, telling it to interact with Atomikos for participating in transactions.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Important Note 1:&lt;/b&gt; that I have a lot of ${database.variable} that I usually load from a property file; you should replace this with whatever values are suitable for your case.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Important Note 2:&lt;/b&gt; The &lt;tt&gt;hibernate.transaction.factory_class&lt;/tt&gt; is explicitly shown as commented out, as I have seen quite a few people using it (due to picking up old Atomikos documentation) when it is NO LONGER NEEDED for things to work properly (see the Atomikos forum thread referenced in the comment).&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;br /&gt;&lt;beans&lt;br /&gt;    xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt;    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;    xmlns:context="http://www.springframework.org/schema/context"&lt;br /&gt;    xsi:schemaLocation="http://www.springframework.org/schema/beans &lt;br /&gt;           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;           http://www.springframework.org/schema/context&lt;br /&gt;           http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;&lt;br /&gt;&lt;br /&gt; &lt;bean id="xaDatasource"&lt;br /&gt;   class="com.atomikos.jdbc.AtomikosDataSourceBean"&lt;br /&gt;   init-method="init" destroy-method="close"&gt;&lt;br /&gt;  &lt;property name="uniqueResourceName"&gt;&lt;value&gt;XADBMS&lt;/value&gt;&lt;/property&gt;&lt;br /&gt;  &lt;property name="xaDataSourceClassName"&gt;&lt;br /&gt;   &lt;value&gt;com.mysql.jdbc.jdbc2.optional.MysqlXADataSource&lt;/value&gt;&lt;br /&gt;  &lt;/property&gt;&lt;br /&gt;  &lt;property name="xaProperties"&gt;&lt;br /&gt;   &lt;props&gt;&lt;br /&gt;    &lt;prop key="URL"&gt;${database.url}&lt;/prop&gt;&lt;br /&gt;    &lt;prop key="user"&gt;${database.username}&lt;/prop&gt;&lt;br /&gt;    &lt;prop key="password"&gt;${database.password}&lt;/prop&gt;&lt;br /&gt;   &lt;/props&gt;&lt;br /&gt;  &lt;/property&gt;&lt;br /&gt;  &lt;property name="minPoolSize" value="${database.minPoolSize}"&gt;&lt;/property&gt;&lt;br /&gt;  &lt;property name="maxPoolSize" value="${database.maxPoolSize}"&gt;&lt;/property&gt;&lt;br /&gt;  &lt;property name="testQuery" value="${database.testQuerySQL}"&gt;&lt;/property&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;  &lt;property name="borrowConnectionTimeout" value="30" /&gt;&lt;br /&gt;  &lt;property name="maintenanceInterval" value="60" /&gt;&lt;br /&gt;--&gt;&lt;br /&gt; &lt;/bean&gt;&lt;br /&gt;&lt;br /&gt; &lt;!-- Data source for acquiring connections (refers to connection pool) --&gt;&lt;br /&gt; &lt;bean id="dataSource"&lt;br /&gt;  class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"&gt;&lt;br /&gt;  &lt;property name="targetDataSource"&gt;&lt;br /&gt;   &lt;ref local="xaDatasource"&gt;&lt;/ref&gt;&lt;br /&gt;  &lt;/property&gt;&lt;br /&gt; &lt;/bean&gt;&lt;br /&gt;&lt;br /&gt; &lt;!-- Persistence context --&gt;&lt;br /&gt;    &lt;bean&lt;br /&gt;        id="entityManagerFactory"&lt;br /&gt;        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;&lt;br /&gt;        &lt;property name="persistenceUnitName" value="MY_PU"&gt;&lt;/property&gt;&lt;br /&gt;        &lt;property name="dataSource" ref="dataSource"&gt;&lt;/property&gt;&lt;br /&gt;        &lt;property name="jpaVendorAdapter"&gt;&lt;br /&gt;            &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"&gt;&lt;br /&gt;                &lt;property name="databasePlatform" value="${database.platform}"&gt;&lt;/property&gt;&lt;br /&gt;                &lt;property name="showSql" value="${database.showSql}"&gt;&lt;/property&gt;&lt;br /&gt;                &lt;property name="generateDdl" value="${database.generateDdl}"&gt;&lt;/property&gt;&lt;br /&gt;            &lt;/bean&gt;&lt;br /&gt;        &lt;/property&gt;&lt;br /&gt;        &lt;property name="jpaProperties"&gt;&lt;br /&gt;            &lt;props&gt;&lt;br /&gt;                &lt;prop key="hibernate.ejb.naming_strategy"&gt;&lt;br /&gt;                 org.hibernate.cfg.ImprovedNamingStrategy&lt;br /&gt;                &lt;/prop&gt;&lt;br /&gt;                &lt;prop key="hibernate.hbm2ddl.auto"&gt;&lt;br /&gt;                 ${database.hibernate.hbm2ddl}&lt;br /&gt;                &lt;/prop&gt;&lt;br /&gt;                &lt;!-- Tell hibernate to use Atomikos (XA-capable) transaction manager&lt;br /&gt;                NO LONGER NEEDED! SEE:&lt;br /&gt;                http://fogbugz.atomikos.com/default.asp?community.6.1436.9&lt;br /&gt;&lt;br /&gt;                &lt;prop key="hibernate.transaction.factory_class"&gt;&lt;br /&gt;                    com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory &lt;br /&gt;                &lt;/prop&gt; &lt;br /&gt;                --&gt;&lt;br /&gt;                &lt;prop key="hibernate.transaction.manager_lookup_class"&gt;&lt;br /&gt;                    com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup &lt;br /&gt;                &lt;/prop&gt; &lt;br /&gt;            &lt;/props&gt;&lt;br /&gt;        &lt;/property&gt;&lt;br /&gt;    &lt;/bean&gt;&lt;br /&gt;&lt;/beans&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Important Note 3:&lt;/b&gt;Remember to use JTA mode for transactions in your persistence.xml, as in:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;persistence-unit name="MY_PU" transaction-type="JTA"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/persistence-unit&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-2266989315575397504?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/2266989315575397504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=2266989315575397504' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/2266989315575397504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/2266989315575397504'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/06/integrating-jetty-spring-aspectj-wicket.html' title='Integrating: Jetty, Spring, AspectJ, Wicket, Hibernate, MySQL, ActiveMQ and Atomikos (web archive scope)'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-1445973819981220941</id><published>2011-06-24T23:12:00.000+03:00</published><updated>2011-06-24T23:12:24.965+03:00</updated><title type='text'>Spring exception translation with AspectJ: bug workaround</title><content type='html'>One of the nice features of Spring is the database access exception translation that simplifies error-handling. Most of us enabled it by adding the &lt;tt&gt;PersistenceExceptionTranslationPostProcessor&lt;/tt&gt; (see the &lt;a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/orm.html#orm-exception-translation"&gt;Exception translation&lt;/a&gt; in the Spring reference).&lt;br /&gt;&lt;br /&gt;Unfortunately, when using a "pure-AspectJ" approach, you will find that the out-of-the-box &lt;tt&gt;JpaExceptionTranslatorAspect&lt;/tt&gt; does not recognize the various JPA dialects out there. &lt;a href="http://forum.springsource.org/showthread.php?111016-Is-JPA-exception-translation-too-simple-Can-you-chain-other-translators-after-it"&gt;I was pretty dissappointed&lt;/a&gt; when I found that JPA access from @Configurable object instances does NOT undergo "proper exception translation".&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a href="http://forum.springsource.org/showthread.php?111016-Is-JPA-exception-translation-too-simple-Can-you-chain-other-translators-after-it&amp;p=368269#post368269"&gt;Martin Deinum's feedback&lt;/a&gt; I quickly "restored" this limitation by creating a custom aspect to invoke the "proper" exception translator (which in my case is the &lt;tt&gt;HibernateJpaDialect&lt;/tt&gt;).&lt;br /&gt;&lt;br /&gt;So, until &lt;a href="https://jira.springsource.org/browse/SPR-6282"&gt;this bug is resolved&lt;/a&gt;, the following aspect will take care of things:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;import org.springframework.dao.DataAccessException;&lt;br /&gt;import org.springframework.orm.jpa.vendor.HibernateJpaDialect;&lt;br /&gt;&lt;br /&gt;public aspect HibernateJpaDialectExceptionTranslationAspect {&lt;br /&gt;    pointcut entityManagerCall(): call(* javax.persistence.EntityManager.*(..)) || call(* javax.persistence..EntityManagerFactory.*(..)) || call(* javax.persistence.EntityTransaction.*(..)) || call(* javax.persistence.Query.*(..));&lt;br /&gt;    &lt;br /&gt;    after() throwing(RuntimeException re): entityManagerCall() {&lt;br /&gt;     HibernateJpaDialect hibernateDialect = new HibernateJpaDialect();&lt;br /&gt;     DataAccessException dex = hibernateDialect.translateExceptionIfPossible(re);&lt;br /&gt;&lt;br /&gt;     if (dex != null) {&lt;br /&gt;      throw dex;&lt;br /&gt;     } else {&lt;br /&gt;      throw re;&lt;br /&gt;     }        &lt;br /&gt;    } &lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-1445973819981220941?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/1445973819981220941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=1445973819981220941' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/1445973819981220941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/1445973819981220941'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/06/spring-exception-translation-with.html' title='Spring exception translation with AspectJ: bug workaround'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-461895634270539119</id><published>2011-06-12T09:34:00.002+03:00</published><updated>2011-06-14T21:53:59.375+03:00</updated><title type='text'>JDeveloper 11g 11.1.2 is out with Maven support (among others)</title><content type='html'>Oracle have released Oracle JDeveloper 11g, version 11.1.2.0.0. Among &lt;a href="http://www.oracle.com/technetwork/developer-tools/jdev/jdev-11gr2-nf-404365.html"&gt;other new features, such as JSF 2,&lt;/a&gt; my favorite is the Maven 2 integration!&lt;br /&gt;&lt;br /&gt;Check it out! Download is available (as usual) from the &lt;a href="http://www.oracle.com/technetwork/developer-tools/jdev/downloads/index.html"&gt;technet site&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;IMPORTANT NOTE: SOA &amp; WebCenter are NOT yet available for this release, so you must stick 11.1.1.5 for such projects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-461895634270539119?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/461895634270539119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=461895634270539119' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/461895634270539119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/461895634270539119'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/06/jdeveloper-11g-1112-is-out-with-maven.html' title='JDeveloper 11g 11.1.2 is out with Maven support (among others)'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-7687611691797025690</id><published>2011-05-27T14:10:00.001+03:00</published><updated>2011-05-27T14:10:50.077+03:00</updated><title type='text'>Using Beehive code (BEA WebLogic &lt;=10.3.1) with recent versions of Oracle WebLogic</title><content type='html'>Recent versions of the WebLogic Server no longer ship with Beehive libraries. As a result, old code that was based on Beehive must ne re-written so as to remove this dependency.&lt;br /&gt;&lt;br /&gt;If you simply &lt;i&gt;must&lt;/i&gt; deploy a Beehive project on a newer WebLogic Server, there is way to achieve that. Oracle will NOT support it of course, but if you decide to take the risk and go ahead with this anyway, here is how to do it:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Locate the library "wlw-system.jar" in your old WebLogic installation. Copy it to the library folder of your target domain (the one that is based on a newer WebLogic version that does not have Beehive). The folder is &lt;tt&gt;${DOMAIN_HOME}/lib&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;Restart your domain's servers (in order to pick up the wlw-system.jar in their classpath)&lt;/li&gt;&lt;li&gt;Using workshop, look up the WebLogic shared libraries that your project uses. These are listed in the project properties at "Java Build Path --&gt; Libraries"&lt;/li&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-p0P6ZaSK0YY/Td-FO-R5fdI/AAAAAAAAAzo/20nSa5m9Hk8/s1600/findRequiredLibs.JPG" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="248" width="400" src="http://2.bp.blogspot.com/-p0P6ZaSK0YY/Td-FO-R5fdI/AAAAAAAAAzo/20nSa5m9Hk8/s400/findRequiredLibs.JPG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;li&gt;For each shared library go to your Workshop preferences under "WebLogic--&gt;Shared Libraries" and click "Edit.." to see the location of the library. Copy all of the EAR/WAR archives for these libraries into some "staging" folder (e.g. &lt;tt&gt;/home/yourusername/app-libs&lt;/tt&gt;)&lt;/li&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-6fD6lPfzCko/Td-GBRK5VjI/AAAAAAAAAzw/ruW6x2pS3LI/s1600/locateLibOnFS.JPG" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="386" width="400" src="http://4.bp.blogspot.com/-6fD6lPfzCko/Td-GBRK5VjI/AAAAAAAAAzw/ruW6x2pS3LI/s400/locateLibOnFS.JPG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;li&gt;Deploy all of the archives (EAR/WAR) that you located in the steps above as shared libraries in your new domain&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;You may now deploy your application on servers where the shared libraries were targeted.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-7687611691797025690?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/7687611691797025690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=7687611691797025690' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/7687611691797025690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/7687611691797025690'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/05/using-beehive-code-bea-weblogic-1031.html' title='Using Beehive code (BEA WebLogic &lt;=10.3.1) with recent versions of Oracle WebLogic'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-p0P6ZaSK0YY/Td-FO-R5fdI/AAAAAAAAAzo/20nSa5m9Hk8/s72-c/findRequiredLibs.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-8831841080008019578</id><published>2011-05-25T21:35:00.001+03:00</published><updated>2011-06-26T15:23:55.754+03:00</updated><title type='text'>Using a different HTTP proxy per each JAX-WS client stub</title><content type='html'>JAX-WS is about to standardize a web service feature, for specifying the use of a different HTTP proxy per each JAX-WS client instance. This can be extremely useful in complex enterprise IT environments, where network security teams are often paranoid and have different proxies for accessing different parts of the network. No longer do you need to host applications modules on different VMs just because they require different proxy settings. Instead of using the global &lt;tt&gt;http.proxyHost&lt;/tt&gt; and &lt;tt&gt;http.proxyPort&lt;/tt&gt;, you can specify a different proxy per JAX-WS client stub.&lt;br /&gt;&lt;br /&gt;Since OFM 11gR1 Patchset 2, one can already exploit this upcoming JAX-WS feature, using WebLogic's &lt;tt&gt;ClientProxyFeature&lt;/tt&gt; API. The approach is described in &lt;a href="http://download.oracle.com/docs/cd/E21764_01/apirefs.1111/e13941/weblogic/wsee/jaxws/proxy/ClientProxyFeature.html"&gt;WebLogic's API Reference&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Although the documentation is pretty straight-forward, it fails to address the fact that the JAX-WS stack will try to retrieve the WSDL during the service instantiation, which leads to the following problem: since the &lt;tt&gt;ClientProxyFeature&lt;/tt&gt; only applies at the web service &lt;i&gt;port&lt;/i&gt; level, the following will fail:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;// The service location is a runtime configuration value...&lt;br /&gt;    URL wsdlURL = new URL(System.getProperty("serviceLocationAtRuntime"));&lt;br /&gt;&lt;br /&gt;    // The below will try to fetch the WSDL from the wsdlURL location&lt;br /&gt;    // The proxy is NOT in effect at this point and will cause a network error&lt;br /&gt;    Service myService = new Service(wsdlURL, ...);&lt;br /&gt;&lt;br /&gt;    // The code will never reach this point; so much for ClientProxyFeature&lt;br /&gt;    ClientProxyFeature cpf = new ClientProxyFeature();&lt;br /&gt;    cpf.setType(Proxy.Type.HTTP);&lt;br /&gt;    cpf.setProxyHost(CONFIG.getProxyHost());&lt;br /&gt;    cpf.setProxyPort(CONFIG.getProxyPort());&lt;br /&gt;    servicePort = myService.getServiceSoap(cpf);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The solution is to bundle the WSDL as a resource in your application and instantiate the service using the local copy of the WSDL. Then, after enabling the proxy, you can set the runtime service address via the &lt;tt&gt;BindingProvider&lt;/tt&gt; API.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;// Don't go over the network to fetch the WSDL; use it from the classpath&lt;br /&gt;    URL wsdlURL = Service.class.getResource("Service.wsdl");&lt;br /&gt;&lt;br /&gt;    // The below will work, but will assume the service address is whatever&lt;br /&gt;    // was defined in your application-bundled WSDL, so we still need to&lt;br /&gt;    // somehow define a run-time location; keep reading to see how we do this&lt;br /&gt;    // after getting the service port&lt;br /&gt;    Service myService = new Service(wsdlURL, ...);&lt;br /&gt;&lt;br /&gt;    // Enable the use of an HTTP proxy for this specific port instance&lt;br /&gt;    ClientProxyFeature cpf = new ClientProxyFeature();&lt;br /&gt;    cpf.setType(Proxy.Type.HTTP);&lt;br /&gt;    cpf.setProxyHost(CONFIG.getProxyHost());&lt;br /&gt;    cpf.setProxyPort(CONFIG.getProxyPort());&lt;br /&gt;    servicePort = myService.getServiceSoap(cpf);&lt;br /&gt;&lt;br /&gt;    // Now that we have the port, configure the service address using&lt;br /&gt;    // a run-time value:&lt;br /&gt;    URL wsdlURL = new URL(System.getProperty("serviceLocationAtRuntime"));&lt;br /&gt;    BindingProvider bp = (BindingProvider)servicePort;&lt;br /&gt;    bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;        wsdlURL.toString());&lt;br /&gt;&lt;br /&gt;    // You can now call the web service via the HTTP proxy&lt;br /&gt;    servicePort.invokeSomeOperation(...);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-8831841080008019578?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/8831841080008019578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=8831841080008019578' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/8831841080008019578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/8831841080008019578'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/05/using-different-http-proxy-per-each-jax.html' title='Using a different HTTP proxy per each JAX-WS client stub'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-289937577174520482</id><published>2011-05-18T11:36:00.000+03:00</published><updated>2011-05-18T11:36:01.999+03:00</updated><title type='text'>Mental note to myself # 8734874243</title><content type='html'>&lt;h1&gt;Oracle SOA Suite 11g -- Repository notes&lt;/h1&gt;&lt;br /&gt;...because I always forget, let me put these down for my future reference!&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Status values for composite instances&lt;/h2&gt;&lt;hr /&gt;&lt;br /&gt;The following values are used for the CUBE_INSTANCE.STATE column of SOA Suite's "SOAINFRA" schema.&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;th&gt;OPEN states&lt;/th&gt; &lt;th&gt;CLOSED states&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;INITIATED&lt;/td&gt;   &lt;td&gt;PENDING_CANCEL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RUNNING&lt;/td&gt;     &lt;td&gt;COMPLETED&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SUSPENDED&lt;/td&gt;   &lt;td&gt;FAULTED&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;FAULTED&lt;/td&gt;     &lt;td&gt;CANCELED&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;            &lt;td&gt;ABORTED&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;            &lt;td&gt;STALE&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;Some SQL to quickly review statistics regarding the state of composite instances within some time window:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: sql"&gt;SELECT&lt;br /&gt;  CASE state&lt;br /&gt;    WHEN 0 THEN 'initiated'&lt;br /&gt;    WHEN 1 THEN 'open.running'&lt;br /&gt;    WHEN 2 THEN 'open.suspended'&lt;br /&gt;    WHEN 3 THEN 'open.faulted'&lt;br /&gt;    WHEN 4 THEN 'closed.pending_cancel'&lt;br /&gt;    WHEN 5 THEN 'closed.completed'&lt;br /&gt;    WHEN 6 THEN 'closed.faulted'&lt;br /&gt;    WHEN 7 THEN 'closed.cancelled'&lt;br /&gt;    WHEN 8 THEN 'closed.aborted'&lt;br /&gt;    WHEN 9 THEN 'closed.stale'&lt;br /&gt;    ELSE 'huh?'&lt;br /&gt;  END state_text,&lt;br /&gt;  COUNT (*)&lt;br /&gt;FROM cube_instance ci&lt;br /&gt;WHERE ci.creation_date &gt;= (:startdate) AND ci.creation_date &lt; (:enddate)&lt;br /&gt;group by ci.state;&lt;/pre&gt;&lt;h2&gt;Status of &amp;ldquo;recently created&amp;rdquo; composite instances&lt;/h2&gt;&lt;hr /&gt;What's going on with recently created instances?&lt;pre class="brush: sql"&gt;SELECT&lt;br /&gt;  CIKEY, STATE, CREATION_DATE, MODIFY_DATE, STATUS, &lt;br /&gt;  COMPOSITE_NAME, COMPONENT_NAME, COMPOSITE_REVISION, DOMAIN_NAME&lt;br /&gt;FROM cube_instance &lt;br /&gt;WHERE creation_date &gt;= SYSDATE-1 AND STATE &lt; 5 AND ROWNUM &lt; 20&lt;br /&gt;ORDER BY creation_date DESC;&lt;/pre&gt;&lt;h2&gt;Status of &amp;ldquo;recently updated&amp;rdquo; composite instances&lt;/h2&gt;&lt;hr /&gt;What's going on with recently updated instances?&lt;pre class="brush: sql"&gt;SELECT&lt;br /&gt;  CIKEY, STATE, CREATION_DATE, MODIFY_DATE, STATUS,&lt;br /&gt;  COMPOSITE_NAME, COMPONENT_NAME, COMPOSITE_REVISION, DOMAIN_NAME&lt;br /&gt;FROM cube_instance &lt;br /&gt;WHERE creation_date &gt;= SYSDATE-1 AND STATE &lt; 5 AND ROWNUM &lt; 20 &lt;br /&gt;ORDER BY modify_date DESC;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-289937577174520482?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/289937577174520482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=289937577174520482' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/289937577174520482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/289937577174520482'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/05/mental-note-to-myself-8734874243.html' title='Mental note to myself # 8734874243'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-4694075399735093183</id><published>2011-04-26T09:30:00.000+03:00</published><updated>2011-04-26T12:18:55.154+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jdbc hibernate'/><title type='text'>BoneCP: a promising new connection pooling library</title><content type='html'>For a long time, we've been stuck with &lt;a href="http://sourceforge.net/projects/c3p0/"&gt;C3P0&lt;/a&gt; and &lt;a href="http://commons.apache.org/dbcp/"&gt;DBCP&lt;/a&gt; in the Java connection pooling arena. These tools, each with its own problems, have served us rather well. Competition from "newcomers" such as &lt;a href="http://proxool.sourceforge.net/"&gt;Proxool&lt;/a&gt; does not seem to have made much difference. At least this is what &lt;a href="http://www.google.com/trends?q=c3p0%2C+dbcp%2C+proxool%2C+bonecp&amp;ctab=0&amp;geo=all&amp;date=2011&amp;sort=1"&gt;Google Trends&lt;/a&gt; comparison indicates.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jolbox.com/"&gt;BoneCP&lt;/a&gt; is a new contender in this area which has caught my attention. It is "Apache v2"-licensed, well-documented and (as far as I can tell from my limited use so far) stable and fast.&lt;br /&gt;&lt;br /&gt;If you're looking for a C3P0/DBCP alternative it's worth giving a try. The only thing I am rather "nervous" about is the size of its community. It seems to be maintained by few individuals, but so are most new OSS projects prior to gaining wider acceptance.&lt;br /&gt;&lt;br /&gt;So go ahead and have a look.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-4694075399735093183?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/4694075399735093183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=4694075399735093183' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/4694075399735093183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/4694075399735093183'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/01/bonecp-promising-new-connection-pooling.html' title='BoneCP: a promising new connection pooling library'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-8063252616584839438</id><published>2011-04-24T16:17:00.004+03:00</published><updated>2011-04-29T02:46:19.919+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><title type='text'>Migrating from Wicket 1.4 to 1.5</title><content type='html'>Wicket 1.5 is just around the corner (currently in its 3rd release candidate). I've been peeking into the upcoming release, by moving some 1.4-based code to run against 1.5-RC3. Lots of stuff is documented in the official Wiki, at &lt;b&gt;&lt;a href="https://cwiki.apache.org/WICKET/migration-to-wicket-15.html"&gt;Migrating to Wicket 1.5&lt;/a&gt;&lt;/b&gt;. Here's my list of notable changes (i.e. what I had to change in order to get things working with 1.5):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;1) Maven dependency has changed&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The core artifact id is now "wicket-core" instead of plain "wicket". Change your dependencies. Other artifacts include: wicket-request, wicket-util, wicket-extensions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;2) It's Java&lt;b&gt;&lt;u&gt;S&lt;/u&gt;&lt;/b&gt;cript (camel-case) not Javascript&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Most classes and methods that contain the term Javascript have switched to camel-case. Capitalize the S (and organize your imports, as some of them have moved) and you'll be back in business.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;3) Header contribution is now implemented in &lt;tt&gt;Component&lt;/tt&gt; and &lt;tt&gt;Behavior&lt;/tt&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Most likely you've been rendering into the HTML header with something along the lines of:&lt;br /&gt;&lt;pre class="brush: java"&gt; new IHeaderContributor() {&lt;br /&gt;  @Override&lt;br /&gt;  public void renderHead(IHeaderResponse response) {&lt;br /&gt;   response.renderJavascriptReference(...);&lt;br /&gt;  }&lt;br /&gt; }&lt;/pre&gt;&lt;br /&gt;No more. The interface IHeaderContributor is now implemented by &lt;tt&gt;Component&lt;/tt&gt; so you can simply override that method and move this code over there. Similarly, &lt;tt&gt;Behavior&lt;/tt&gt; has acquired the nice &lt;tt&gt;public void renderHead(Component component, IHeaderResponse response)&lt;/tt&gt; routine which will basically let you do the same thing while holding a reference to the component where the behavior is attached. This is pretty straight-forward if you're updating a web page (see the Wiki link above). In short however, if you've been extending &lt;tt&gt;HeaderContributor&lt;/tt&gt; itself, you can simply switch to extending a Behavior:&lt;br /&gt;&lt;pre class="brush: java"&gt;public class MyHeaderContributor extends Behavior {&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt; public static final JavaScriptResourceReference MY_JS = new JavaScriptResourceReference(&lt;br /&gt;   MyHeaderContributor.class, "some-javascript-resource.js");&lt;br /&gt;&lt;br /&gt; public MyHeaderContributor() {&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void renderHead(Component component, IHeaderResponse response) {&lt;br /&gt;  response.renderJavaScriptReference(MY_JS);&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;Of course, most likely there's already some component/page/behavior class where you'd simply move the code for rendering the header contribution.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;4) Template-base CSS and JavaScript (TextTemplateHeaderContributor) must now be contributed to the header.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Just as shown immediately above, you must use the &lt;tt&gt;renderHead()&lt;/tt&gt; method of &lt;tt&gt;Component&lt;/tt&gt; or &lt;tt&gt;Behavior&lt;/tt&gt;. So now you'd render your template with:&lt;br /&gt;&lt;pre class="brush: java"&gt;@Override&lt;br /&gt;public void renderHead(IHeaderResponse response) {&lt;br /&gt; super.renderHead(response);&lt;br /&gt;&lt;br /&gt; PackageTextTemplate template = new PackageTextTemplate(&lt;br /&gt;   YourComponentOrPage.class, "YourJavaScriptResource.js");&lt;br /&gt; response.renderJavaScript(template.asString(yourVariablesModel), "someMarkupId");&lt;br /&gt;}&lt;/pre&gt;&lt;span style="font-weight:bold;"&gt;5) Page mounting&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Have a look at the new API for mountPage() and mountPackage() and adjust accordingly. For example:&lt;pre class="brush: java"&gt;mount(new IndexedParamUrlCodingStrategy("/staff/details", StaffDetailsPage.class));&lt;/pre&gt; becomes:&lt;pre class="brush: java"&gt;mountPage("/staff/details", StaffDetailsPage.class));&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;6) Mounting of global resources&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;tt&gt;Application&lt;/tt&gt; now has methods for mounting resources. Their usage is rather straight-forward. Since the &lt;tt&gt;SharedResources.putClassAlias(...)&lt;/tt&gt; method no longer exists, if you used to mount resources globally like this:&lt;br /&gt;&lt;pre class="brush: java"&gt;    protected void init() {&lt;br /&gt;        super.init();&lt;br /&gt;        getSharedResources().putClassAlias(org.apache.wicket.Application.class,&lt;br /&gt;            "global");&lt;br /&gt;        getSharedResources().add("images", new MyImageResources());&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;You will now have to use the &lt;tt&gt;mountResource()&lt;/tt&gt; method like this:&lt;pre class="brush: java"&gt;    mountResource("imgres", new ResourceReference(Application.class,&lt;br /&gt;            "imgres") {&lt;br /&gt;        private static final long serialVersionUID = 1L;&lt;br /&gt;        MyImageResources imgres = new ImageResources();&lt;br /&gt;    &lt;br /&gt;        @Override&lt;br /&gt;        public IResource getResource() {&lt;br /&gt;            return imgres;&lt;br /&gt;        }&lt;br /&gt;    });&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-8063252616584839438?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/8063252616584839438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=8063252616584839438' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/8063252616584839438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/8063252616584839438'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/01/migrating-from-wicket-14-to-15.html' title='Migrating from Wicket 1.4 to 1.5'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-7864433904252727628</id><published>2011-04-22T12:29:00.003+03:00</published><updated>2011-04-22T12:51:11.008+03:00</updated><title type='text'>Jetty 7: add security realm in embedded server</title><content type='html'>It's been more than a year since Jetty 7 was released. Still, even today, there exists code based on the 6.x series that has not been subjected to the process of being upgraded to the new version.&lt;br /&gt;&lt;br /&gt;Most of the changes have already been documented in the web, so anyone that is starting to switch now, should find it easy: in most cases a quick search with terms describing your problem will immediately get you the answer to any question that may arise.&lt;br /&gt;&lt;br /&gt;Surprisingly, this is not always the case. For example, A typical issue is how to configure a user realm (now referred to as a "loginService" in Jetty 7). Failing to configure this will cause a "No LoginService for XXX" exception. A junior developer was fighting with this and had located a nice set of instructions on how to do this with maven (which we use for our builds). The &lt;span style="font-weight: bold;"&gt;jetty-&lt;/span&gt;maven-plugin (note that it is no longer maven-jetty-plugin, the term "jetty" was moved in front of "maven") by editing the pom.xml to include it in the plugin configuration:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;            &lt;plugin&gt;&lt;br /&gt;                &lt;groupid&gt;org.mortbay.jetty&lt;/groupid&gt;&lt;br /&gt;                &lt;artifactid&gt;jetty-maven-plugin&lt;/artifactid&gt;&lt;br /&gt;                &lt;version&gt;${jetty.version}&lt;/version&gt;&lt;br /&gt;                &lt;configuration&gt;&lt;br /&gt;                    &lt;loginservices&gt;&lt;br /&gt;                        &lt;loginservice implementation="org.eclipse.jetty.security.HashLoginService"&gt;&lt;br /&gt;                            &lt;name&gt;Test Realm&lt;/name&gt;&lt;br /&gt;                            &lt;config&gt;${basedir}/src/test/resources/jetty-test-realm.properties&lt;/config&gt;&lt;br /&gt;                        &lt;/loginservice&gt;&lt;br /&gt;                    &lt;/loginservices&gt;&lt;br /&gt;                &lt;/configuration&gt;&lt;br /&gt;                &lt;dependencies&gt;&lt;br /&gt;                    &lt;dependency&gt;&lt;br /&gt;                        &lt;groupid&gt;org.eclipse.jetty&lt;/groupid&gt;&lt;br /&gt;                        &lt;artifactid&gt;jetty-servlets&lt;/artifactid&gt;&lt;br /&gt;                        &lt;version&gt;${jetty.version}&lt;/version&gt;&lt;br /&gt;                    &lt;/dependency&gt;&lt;br /&gt;                &lt;/dependencies&gt;&lt;br /&gt;            &lt;/plugin&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However, this only applies when you use the jetty:run goal to launch your application.&lt;br /&gt;&lt;br /&gt;What happens if you want to apply this in your IDE? We usually have a "test launcher" for running the application within the IDE to debug stuff. This launches Jetty from a simple Java application. In this case, you have to configure a realm in your code. I was surprised to be asked how to do this, by a developer that was aware of the POM changes required, but could not locate the respective changes for applying to the code-based launching of Jetty. So this is for all the search engines out there:&lt;br /&gt;&lt;br /&gt;If you get:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;java.lang.IllegalStateException: No LoginService for org.eclipse.jetty.security.authentication.BasicAuthenticator in org.eclipse.jetty.security.ConstraintSecurityHandler&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then try launching as follows from your code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;  Server server = new Server();&lt;br /&gt;&lt;br /&gt;  SocketConnector connector = new SocketConnector();&lt;br /&gt;  // Set some timeout options to make debugging easier.&lt;br /&gt;  connector.setMaxIdleTime(1000 * 60 * 60);&lt;br /&gt;  connector.setSoLingerTime(-1);&lt;br /&gt;  connector.setPort(PORT);&lt;br /&gt;  server.addConnector(connector);&lt;br /&gt;&lt;br /&gt;  WebAppContext webAppCtx = new WebAppContext();&lt;br /&gt;  webAppCtx.setServer(server);&lt;br /&gt;  webAppCtx.setContextPath("/");&lt;br /&gt;  webAppCtx.setWar("src/main/webapp");&lt;br /&gt;&lt;br /&gt;  HashLoginService dummyLoginService = new HashLoginService(&lt;br /&gt;    "TEST-SECURITY-REALM");&lt;br /&gt;  webAppCtx.getSecurityHandler().setLoginService(dummyLoginService);&lt;br /&gt;&lt;br /&gt;  server.setHandler(webAppCtx);&lt;br /&gt;&lt;br /&gt;  try {&lt;br /&gt;   server.start();&lt;br /&gt;   System.in.read();&lt;br /&gt;   server.stop();&lt;br /&gt;   server.join();&lt;br /&gt;  } catch (Exception e) {&lt;br /&gt;   e.printStackTrace();&lt;br /&gt;   System.exit(100);&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-7864433904252727628?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/7864433904252727628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=7864433904252727628' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/7864433904252727628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/7864433904252727628'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/04/jetty-7-add-security-realm-in-embedded.html' title='Jetty 7: add security realm in embedded server'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-7564903091292898833</id><published>2011-01-19T22:39:00.008+02:00</published><updated>2011-01-26T13:38:49.373+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software quality'/><category scheme='http://www.blogger.com/atom/ns#' term='sdlc'/><title type='text'>The "software factory"</title><content type='html'>Today I was contemplating that I've been working in software R&amp;amp;D for more than 15 years now. I actually started out in my mid teens, developing a CRM application for our family business. However, my first real job was at 20, in my 3rd year as a CS student.&lt;br /&gt;&lt;br /&gt;During this time, I've experienced a broad spectrum of environments: from the small, rambo-programmer-syle organizations, to the large behemoths with distributed development teams and CMMI 4 processes. I have participated in projects using various development methodologies (V model, unified process, scrum agile, ...). I have produced software where "the code is the documentation", but also worked in government projects where full end-to-end traceability was required (in fact, looking back I'm not sure whether the team spent more time writing code and testing, or fighting with the Word add-on for Rational Requisite Pro and drawing UML).&lt;br /&gt;&lt;br /&gt;This experience in varying work environments and processes has led me to settle in my mind, what I call the "software factory" infrastructure.&lt;br /&gt;&lt;blockquote&gt;Just as all businesses that procure IT systems to help them automate their business processes, so too  must solution delivery departments procure systems that support the delivery process.&lt;/blockquote&gt;So, here is my list of essential tools any software development shop needs to have:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Distributed&lt;/span&gt; SCM repository (&lt;a href="http://mercurial.selenic.com/"&gt;Mercurial&lt;/a&gt; &amp;amp; &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt; are both excellent)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Issue tracking and planning (&lt;a href="http://www.redmine.org/"&gt;Redmine&lt;/a&gt; is my favorite, but &lt;a href="http://trac.edgewall.org/"&gt;Trac&lt;/a&gt; is also good).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Headless builds (I'm fluent with &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt;, but you may want to check out alternatives such as &lt;a href="http://buildr.apache.org/"&gt;Buildr&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Continuous Integration (&lt;a href="http://www.jenkins-ci.org/"&gt;Jenkins&lt;/a&gt; is my cup of tee here. Note that this was formerly known as &lt;a href="http://hudson-ci.org/"&gt;Hudson&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A provisioning repository for binaries, such as nightly builds and releases (&lt;a href="http://nexus.sonatype.org/"&gt;Nexus&lt;/a&gt; is an ideal fit for Maven)&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;I'm even running my one-man personal projects using the above.&lt;br /&gt;&lt;br /&gt;I also like some code metrics and quality assurance, but I left it outside the list above as I am not very settled on this topic. Though if you're interested in this, I suggest you look into &lt;a href="http://pmd.sourceforge.net/"&gt;PMD&lt;/a&gt;, &lt;a href="http://checkstyle.sourceforge.net/"&gt;CheckStyle&lt;/a&gt; and &lt;a href="http://www.sonarsource.org/"&gt;Sonar&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-7564903091292898833?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/7564903091292898833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=7564903091292898833' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/7564903091292898833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/7564903091292898833'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/01/software-factory.html' title='The &quot;software factory&quot;'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-7264012691533621352</id><published>2011-01-16T11:50:00.005+02:00</published><updated>2011-01-24T08:43:32.010+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ofm'/><category scheme='http://www.blogger.com/atom/ns#' term='integration'/><category scheme='http://www.blogger.com/atom/ns#' term='middleware'/><category scheme='http://www.blogger.com/atom/ns#' term='vodafone'/><category scheme='http://www.blogger.com/atom/ns#' term='fusion middleware'/><title type='text'>It's not the ESB!!!</title><content type='html'>Being the IT architect responsible for integration at Vodafone Greece, has recently put me in the spotlight of several business and technical teams in the company. The reason is that we made a major technical revamp of our integration architecture, which went live in two phases (first in August, the in October). As a result, the systems integration team received a lot of unwanted attention: if anything broke, we were the first ones to point the finger at!&lt;br /&gt;&lt;br /&gt;I guess it's normal that upon every major IT deployment, there's always a few quirks and glitches to take care of. Middleware however (by nature) lies at focal point of the IT systems. Nearly all "online" business is either directly or indirectly affected by the ESB, our process engine, rules engine, etc.&lt;br /&gt;&lt;br /&gt;Therefore, I was very satisfied recently when a colleague uttered the words:&lt;br /&gt;&lt;blockquote&gt;"Oh, I don't thing it's the ESB... It's probably something in the [system X's] blah blah..."&lt;/blockquote&gt;It appears that people are beginning to trust the new middleware systems... and the should! We passed our first Christmas/New Year's shopping rush with ZERO incidents! For months now, we have been through numerous counts of problem troubleshooting, only to find that  some sytem X is responsible for problem Y. And now, slowly but steadily, the psychology that "the middleware is stable" is settling in throughout the company.&lt;br /&gt;&lt;br /&gt;We're out of the spotlight... and loving it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-7264012691533621352?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/7264012691533621352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=7264012691533621352' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/7264012691533621352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/7264012691533621352'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/01/its-not-esb.html' title='It&apos;s not the ESB!!!'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1780439233174741141.post-7555187138707648335</id><published>2011-01-06T22:59:00.015+02:00</published><updated>2011-01-16T12:07:09.638+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wiquery'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><title type='text'>Applying jQuery UI effects in Wicket, using wiQuery</title><content type='html'>The &lt;a href="http://www.wiquery.org/"&gt;wiQuery project&lt;/a&gt; neatly integrates two of my favourite frameworks: jQuery(UI) with Wicket. This post discusses how you can exploit jQuery UI effects using wiQuery.&lt;br /&gt;&lt;br /&gt;The jQuery core effects (fade in/out, animate, etc) live in package &lt;span style=";font-family:verdana;font-size:85%;"  &gt;org.odlabs.wiquery.core.effects&lt;/span&gt;. The extended jQueryUI effects (bounce, explode, etc) live in package &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;org.odlabs.wiquery.ui.effects&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Adding an effect to a component requires that you simply add an EffectBehavior to it. While this is enough for the &lt;a href="http://api.jquery.com/category/effects"&gt;effects of jQuery core&lt;/a&gt;, it is not sufficient for the additional &lt;a href="http://jqueryui.com/docs/effect/"&gt;effects included in jQueryUI&lt;/a&gt;. Fortunately, the difference in using a jQuery UI effect is minimal: the approach is basically identical, except that you must additionally override the contribute(...) method, to make sure that the relevant JavaScript is added to the page.&lt;br /&gt;&lt;br /&gt;So assuming you are trying to "bounce" a simple label:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: html"&gt;&amp;lt;span wicket:id="myLabel"&amp;gt;This should bounce...&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here is how you would overrided contribute(...) to include the extended effect.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;package test.wiquery;&lt;br /&gt;&lt;br /&gt;import org.apache.wicket.PageParameters;&lt;br /&gt;import org.apache.wicket.markup.html.WebPage;&lt;br /&gt;import org.apache.wicket.markup.html.basic.Label;&lt;br /&gt;import org.odlabs.wiquery.core.commons.WiQueryResourceManager;&lt;br /&gt;import org.odlabs.wiquery.core.effects.EffectBehavior;&lt;br /&gt;import org.odlabs.wiquery.ui.effects.BounceEffect;&lt;br /&gt;import org.odlabs.wiquery.ui.effects.EffectsHelper;&lt;br /&gt;&lt;br /&gt;public class HomePage extends WebPage {&lt;br /&gt;&lt;br /&gt;private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt;public HomePage(final PageParameters parameters) {&lt;br /&gt; Label myLabel = new Label("myLabel", "this should bounce");&lt;br /&gt; BounceEffect effect = new BounceEffect();&lt;br /&gt; EffectBehavior eb = new EffectBehavior(effect) {&lt;br /&gt;  private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public void contribute(WiQueryResourceManager wiQueryResourceManager) {&lt;br /&gt;   EffectsHelper.bounce(wiQueryResourceManager);&lt;br /&gt;  }&lt;br /&gt; };&lt;br /&gt; myLabel.add(eb);&lt;br /&gt; add(myLabel);&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1780439233174741141-7555187138707648335?l=alexandros-karypidis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://alexandros-karypidis.blogspot.com/feeds/7555187138707648335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1780439233174741141&amp;postID=7555187138707648335' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/7555187138707648335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1780439233174741141/posts/default/7555187138707648335'/><link rel='alternate' type='text/html' href='http://alexandros-karypidis.blogspot.com/2011/01/jquery-ui-effects-with-wiquery.html' title='Applying jQuery UI effects in Wicket, using wiQuery'/><author><name>Alexandros Karypidis</name><uri>http://www.blogger.com/profile/10459946394097134296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
