[jBPM] - jBPM 5 (and Drools) database testing
by Marco Rietveld
Marco Rietveld [http://community.jboss.org/people/marco.rietveld] modified the document:
"jBPM 5 (and Drools) database testing"
To view the document, visit: http://community.jboss.org/docs/DOC-17071
--------------------------------------------------------------
This article describes how to configure the jBPM project so that unit tests connect to a database or your choice instead of using the default H2 (in-memory) database.
| * Overview of modifications (#overview)
* Explanation (#explanations)* The pom.xml and maven settings (#pomAndSettings)
* Filtering and the datasource.properties and persistence.xml files (#filtering)
* Using PersistenceUtil in unit tests (#persistenceUtil)
* Summary (#summary)
* Appendix (#appendix) |
h3. Overview of modifications
The jbpm project root pom.xml contains:
** Properties to be used to connect to the database of choice
** A database profile that can be used in order to inject a dependency for the jdbc driver jar for the database
** An example profile, which has been commented out, which shows how do test without using a settings file
2. A org.jbpm.persistence.util.PersistenceUtil class has been added to the jbpm-persistence-jpa module.
3. The jbpm-persistence-jpa module now also has a test-jar goal: the test-jar produced contains the PersistenceUtil class mentioned above.
4. In the modules in which persistence is used during testing, the following modifications have been made:
* A datasource.properties file has been added to the src/test/resources directory.
* The pom.xml of the module has been modified so that filtering has been turned on for the src/test/resources directory.
* The persistence.xml file in src/test/resources/META-INF has been modified so that the hibernate.connection.* properties use variables.
How all of these modifications fit together is explained in the following section.
h3. Explanation
We essentially use maven to inject the values we want into the persistence configuration.
Unfortunately, because XA datasource configuration is not uniform across different database vendors, there is also a utility class (org.jbpm.persistence.util.PersistenceUtil) which contains database specific XA datasource configuration and which we use to initiate and configure the XA datasource when testing.
An explanation follows the diagram below:
h5. http://community.jboss.org/servlet/JiveServlet/showImage/102-17071-9-1676... http://community.jboss.org/servlet/JiveServlet/downloadImage/102-17071-9-...
h5. A. The pom.xml and maven settings:
Properties
The jbpm project root pom (jbpm artifact) contains a number of maven.* properties: a number of these settings are empty, and those that aren't are set to the h2 defaults.
However, we can create a local settings.xml file and run the following:
mvn clean test -ssettings-db.xml -Pdatabase
(The -Pdatabase is explained below)
By filling a local settings.xml file with the jdbc values that we want for, for example, our local PostgreSQL database, we can then use those values later on when running our tests.
Otherwise, we can also directly modify the pom.xml itself and fill the values in there.
Using a profile to inject a dependency
The -Pdatabase option in the mvn command above tells maven to use the profile that has an id of "database".
In the project root pom, we have also defined a "database" profile that uses a dependency. By setting the maven.jdbc.driver.jar property (in either the pom.xml or the settings.xml file that you use) to the path of the appropriate jdbc driver class jar, we can then ensure that the database specific driver classes are available to our tests.
[Depending on demand, we could also add properties to the pom.xml so that the groupId, artifactId, and version of the driver class jar (instead of a system path) are defined and used]
h5. B. Filtering and the datasource.properties and persistence.xml files:
In the pom.xml of the module in which the testing is done (for example, jbpm-persistence-jpa or jbpm-bam), the following has also been added to the <build> section of the module pom:
<build>
...
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
...
</build>
When maven runs the process-test-resources goal, it +filters+ all files in and under the src/main/resources directory. Any properties that have been defined in the (effective) pom.xml being processed by maven, will be replaced with the values that have been assigned to them.
In this case, the following two files in src/main/resources that are filtered for us:
* datasource.properties
* META-INF/persistence.xml
In the PersistenceUtil class, we read in the datasource.properties file. The test-compile and process-test-resources goals ensure that the filtered version of this file -- where all maven variables have been replaced with their assigned values -- is placed in the same class path as the rest of the test classes and jars (target/, namely).
hibernate.xml is used by Hibernate/JPA when we instantiate an EntityManager.
h5. C. Using the PersistenceUtil in unit tests:
Lastly, when we write any unit tests that use persistence, instead of configuring the datasource and entityManager ourselves, we use the static methods made available to us from the PersistenceUtil class.
In our test class, we can use something like the following code:
import static org.jbpm.persistence.util.PersistenceUtil.*;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
...
import org.junit.After;
import org.junit.Before;
import bitronix.tm.TransactionManagerServices;
import bitronix.tm.resource.jdbc.PoolingDataSource;
public class MyPersistenceTest {
private PoolingDataSource ds1;
private EntityManagerFactory emf;
@Before
public void setUp() throws Exception {
ds1 = setupPoolingDataSource();
ds1.init();
emf = Persistence.createEntityManagerFactory( PERSISTENCE_UNIT_NAME );
}
@After
public void tearDown() throws Exception {
emf.close();
ds1.close();
}
setupPoolingDataSource() is a static method from the PersistenceUtil Class.
This method does the following:
1. It retrieves the properties stored in datasource.properties
2. It initializes a PoolingDataSource object.
3. Depending on the driver class that's been specified, other properties are injected into the PoolingDataSource instance. * Depending on the database specific PoolingDataSource implementations, different properties are necessary to initiate the XA datasoruce.
h3. Summary
In order to run the unit tests on a different database, you can do one of two things:
If you want to run all of the tests with a specific database, the easiest way to do this is the following:
1. Download the appropriate jdbc driver class jar for your database.
2. Fill a settings file with the appropriate values (including the path to your jdbc driver class jar)
3. Run mvn -Pdatabase -ssettings.xml clean test !
Otherwise, if you are developing or debugging unit tests and running them with a specific database, do the following:
1. Ensue that the appropriate jdbc driver classes are available by doing one of the following: * Download the appropriate jdbc driver class jar for your database and use the path to that jar.
* Modify the dependency in the database profile that it points to the correct jdbc driver jar.
2. Modify the properties in the jBPM project root pom so that they contain the correct values for your database.
3. Run mvn -Pdatabase clean test-compile
4. Debug/run your unit tests.
h3. Appendix
The following is an example of a maven settings.xml file that you could use to test on a local PostgreSQL database that contained a "jbpm5" schema (with user "jbpm5" and password "jbpm5")
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<profiles>
<profile>
<id>database</id>
<properties>
<maven.hibernate.dialect>org.hibernate.dialect.PostgreSQLDialect</maven.hibernate.dialect>
<maven.datasource.classname>org.postgresql.xa.PGXADataSource</maven.datasource.classname>
<maven.jdbc.driver.class>org.postgresql.Driver</maven.jdbc.driver.class>
<maven.jdbc.db.name>jbpm5</maven.jdbc.db.name>
<maven.jdbc.db.port>5432</maven.jdbc.db.port>
<maven.jdbc.db.server>localhost</maven.jdbc.db.server>
<maven.jdbc.driver.jar>/home/awesomeUser/workspace/jbpm5/lib/postgresql-8.4-702.jdbc3.jar</maven.jdbc.driver.jar>
<maven.jdbc.username>jbpm5</maven.jdbc.username>
<maven.jdbc.password>jbpm5</maven.jdbc.password>
<maven.jdbc.url>jdbc:postgresql://localhost:5432/jbpm5</maven.jdbc.url>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>database</activeProfile>
</activeProfiles>
</settings>
--------------------------------------------------------------
Comment by going to Community
[http://community.jboss.org/docs/DOC-17071]
Create a new document in jBPM at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=102&co...]
13 years, 3 months
[jBPM] - How to complete custom Work Item Handler
by Miljenko Norsic
Miljenko Norsic [http://community.jboss.org/people/mnorsic] created the discussion
"How to complete custom Work Item Handler"
To view the discussion, visit: http://community.jboss.org/message/628066#628066
--------------------------------------------------------------
Hi all,
I have a question about custom work item handlers. I've seen a way to do it (chapter 13 on domain-specific processes in JBPM User Guide), but the samples are mostly simple, and include a TestWorkItemHandler that simply prints out work item information and then calls completeWorkItem() method on WorkItemManager object.
On the other hand, if I have an access to a ksession, I can call
ksession.getWorkItemManager().completeWorkItem(id, params);
The requirements for my scenario include some custom work item handlers that are going to contain some external business logic, but can stay in an active state (it means that work item handler would not call completeWorkItem() and abortWorkItem()). And everything is persisted in a database and I cannot remember work item in the meantime because there is going to be a batch job that is going to process all pending processes.
Is there a way to continue with the custom work handler at the place where it stopped? If so, how can I wake up that custom work item handler?
I did not see a way to send a signal to a custom work item handler, is it possible?
Thanks,
Miljenko
--------------------------------------------------------------
Reply to this message by going to Community
[http://community.jboss.org/message/628066#628066]
Start a new discussion in jBPM at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&cont...]
13 years, 3 months
[JBoss Messaging] - JMS createConnection on ConnectionFactory failed for NPE
by Aparna Rallabandi
Aparna Rallabandi [http://community.jboss.org/people/aparnaralla] created the discussion
"JMS createConnection on ConnectionFactory failed for NPE"
To view the discussion, visit: http://community.jboss.org/message/628848#628848
--------------------------------------------------------------
I have a JMS producer on Jboss 6.0.0.M2.
Used the Producer from the example below in my application running on Jboss.
I use the docs\examples\jms\examples\queue\...\QueueExample.java and modified it to be a MessageListener (Modified file is attached) and that works with my JMS producer.
Now we have a standalone J2SE Swing application which need to be the listener and show popups for each event it receives.
When this standalone app tries to create a connection it fails at createConnection with the following StackTrace.
Any pointers or direction you could give will be very helpful.
Regards,
Aparna
INFO line:54 file:JmsConsumer.java method:setup()
"Queue /queue/testQueue exists"
DEBUG line:615 file:Client.java method:connect()
"Client[19176986:3j001-srvfa8-gt1udu6a-1-gt1uduu1-4].connect(null)"
TRACE line:616 file:Client.java method:connect()
"Client[19176986:3j001-srvfa8-gt1udu6a-1-gt1uduu1-4]: metadata = null"
TRACE line:320 file:PropertyEditors.java method:mapJavaBeanProperties()
"Mapping properties for bean: SocketClientInvoker[ee558f, bisocket://localhost.localdomain:4457]"
TRACE line:365 file:PropertyEditors.java method:mapJavaBeanProperties()
"Property editor found for: marshaller, editor: java.beans.PropertyDescriptor@17ff5aaf, setter: public void org.jboss.remoting.MicroRemoteClientInvoker.setMarshaller(org.jboss.remoting.marshal.Marshaller)"
TRACE line:373 file:PropertyEditors.java method:mapJavaBeanProperties()
"Failed to find property editor for: marshaller"
TRACE line:384 file:PropertyEditors.java method:mapJavaBeanProperties()
"Failed to write property"
java.lang.NullPointerException
at org.jboss.util.propertyeditor.PropertyEditors.mapJavaBeanProperties(PropertyEditors.java:377)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.mapJavaBeanProperties(MicroSocketClientInvoker.java:1359)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.setup(MicroSocketClientInvoker.java:533)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.<init>(MicroSocketClientInvoker.java:292)
at org.jboss.remoting.transport.socket.SocketClientInvoker.<init>(SocketClientInvoker.java:78)
at org.jboss.remoting.transport.bisocket.BisocketClientInvoker.<init>(BisocketClientInvoker.java:166)
at org.jboss.remoting.transport.bisocket.TransportClientFactory.createClientInvoker(TransportClientFactory.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.remoting.InvokerRegistry.loadClientInvoker(InvokerRegistry.java:453)
at org.jboss.remoting.InvokerRegistry.createClientInvoker(InvokerRegistry.java:352)
at org.jboss.remoting.Client.connect(Client.java:632)
at org.jboss.remoting.Client.connect(Client.java:582)
at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate.createClient(ClientConnectionFactoryDelegate.java:333)
at http://org.jboss.jms.client.delegate.clientconnectionfactorydelegate.org/ org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate.org$jboss$jms$client$delegate$ClientConnectionFactoryDelegate$getClientAOPStack$aop(ClientConnectionFactoryDelegate.java:243)
at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate.getClientAOPStack(ClientConnectionFactoryDelegate.java)
at org.jboss.jms.client.ClientAOPStackLoader.load(ClientAOPStackLoader.java:75)
at org.jboss.jms.client.JBossConnectionFactory.createConnectionInternal(JBossConnectionFactory.java:192)
at org.jboss.jms.client.JBossConnectionFactory.createConnection(JBossConnectionFactory.java:87)
at org.jboss.jms.client.JBossConnectionFactory.createConnection(JBossConnectionFactory.java:82)
at rt.controller.JmsConsumer.setup(JmsConsumer.java:56)
at rt.controller.JmsConsumer.<init>(JmsConsumer.java:44)
--------------------------------------------------------------
Reply to this message by going to Community
[http://community.jboss.org/message/628848#628848]
Start a new discussion in JBoss Messaging at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&cont...]
13 years, 3 months