Getting/Using services deployed in JBoss AS 5.x

September 28, 2010 Leave a comment

JBoss AS Version 5 and above used the JBoss MicroContainer project to accomplish the service management/dependency injection. If we want to write a service that uses a JBoss Server service, like the ‘HAPartitionService’ for example, the below shows several ways that can be done.

1. Using JBoss MC’s xml syntax
This is the most common and recommended way to do. Below is the JBoss RiftSaw Clustering service that uses the ‘HAPartitonService’ from JBoss AS Cluster.

<bean name=" riftsawclusteringservice"="">
<property name="haPartition"><inject bean="HAPartition"></inject></property>
<property name="bpelEngineName">bpel/Engine</property>
<depends>BPELEngine</depends>

See Ales’ Advanced Dependency Injections article for more about MC’s xml syntax.

2. Using JBoss MC’s service programmatically
This way actually is the main topic for this blog entry. If you are a Spring framework user, you would know you can use BeanFactory or ApplicationContext to get the service bean. Then in JBoss, you would wonder, whats the equivalent way to do this?

1) org.jboss.kernel.Kernel, this is the service that has the KernelController and ControllerContext that we need for getting the service. so firstly, you can define a service in -jboss-bean.xml that injects the Kernel service, like the following:

<!--
Locate the single instance of the kernel
-->
<bean name="org.jboss.soa.bpel.runtime.util:service=KernelLocator"
class="org.jboss.soa.bpel.runtime.integration.KernelLocator">
<property name="kernel">
<inject bean="jboss.kernel:service=Kernel" />
</property>
</bean>

We’ve defined above class as following:

package org.jboss.soa.bpel.runtime.integration;
public class KernelLocator
{
private static Kernel kernel;

public static Kernel getKernel()
{
return KernelLocator.kernel;
}

public void setKernel(Kernel kernel)
{
KernelLocator.kernel = kernel;
}
}

2) Use the KernelController and ControllerContext to get the service that we defined in *-jboss-bean.xml.
Below is the code to actually obtain the started service out of JBoss AS.

public class KernelAwareSPIFactory
{
@SuppressWarnings("unchecked")
public <T> T getKernelProvidedSPI(String beanName, Class<T> spiArtifact)
{
KernelController controller = KernelLocator.getKernel().getController();
ControllerContext ctx = controller.getInstalledContext(beanName);
return (T)ctx.getTarget();
}
}

In the end, let’s take an example from RiftSaw code base to show how it was used.

In RiftSaw, we’ve defined a ServerConfig interface.

public interface ServerConfig
{
/** The default bean name */
String BEAN_NAME = "org.jboss.soa.bpel.runtime.util:service=ServerConfig";

String getImplementationTitle();

String getImplementationVersion();

File getServerTempDir();

File getServerDataDir();

String getWebServiceHost();

int getWebServicePort();

.....
}

And then we’ve had the ServerConfigImpl class.

public class ServerConfigImpl implements ServerConfig
{
....
}

With this implementation, we’ve defined the ServerConfig service in the *-jboss-bean.xml as following.

<!--
ServerConfig
-->
<bean name="org.jboss.soa.bpel.runtime.util:service=ServerConfig"
class="org.jboss.soa.bpel.runtime.integration.ServerConfigImpl">
<property name="mbeanServer"><inject bean="JMXKernel" property="mbeanServer"/></property>
<property name="webServiceHost">${jboss.bind.address}</property>
</bean>

Now, finally let’s see how we get this ServerConfig Service in our code.

ServerConfig = new KernelAwareSPIFactory().getKernelProvidedSPI(
"org.jboss.soa.bpel.runtime.util:service=ServerConfig", ServerConfig.class

And then, here you go, you’ve got the ServerConfig service that is in the JBoss AS.

Hope this can help people who are doing integration with JBoss AS a little bit.

PS: Thanks Glen for pointing out some grammar errors that I did earlier. As what we used to say “your patch has been applied, thanks a lot. ;)”

Categories: Java, JBoss, Riftsaw

Install Mysql and Postgres in Mac OS through MacPorts

August 19, 2010 Leave a comment

Here are two greats links on how to installing mysql and postgres on to your Mac OS.

1.Installing PostgreSQL on Leopard using MacPorts
2.Installing MySQL on Mac OS X Leopard using MacPorts

Categories: Database

Exploring ODE part V: implemenation of scheduler-simple module.

July 26, 2010 Leave a comment

In Ode/RiftSaw, we make the process execution as asynchronous, which means that if you running a bpel process, we are using more than one thread to accomplish this invocation.

And this is what the scheduler-simple module for, it takes care of putting a task into database and pull tasks out of database and how to run them. Lets make a simple example here, say your bpel process has a invoke Activity to invoke an external web service. In Ode, just right before entering invoke Activity, we’ve created a job that captures this invoke activity information, and store it into the database. Because once we’ve started Ode Bpel Server, we already started a background thread that checks this ode_job table periodically, once we’ve found that there is a job needs to be executed, it will load it from database, put it into memory, and then submit it to the ExecutorService for execution.

In this blogpost, we will examine this module’s architecture and important APIs.

First is the Task API, this is the parent class for Job and SchedulerTask.


class Task {
/** Scheduled date/time. */
public long schedDate;

Task(long schedDate) {
this.schedDate = schedDate;
}
}

It is very simple, just had a scheduled date for its execution.
Next, we will see the Job’s API, Job is for invoking an external service and like. we’ve put all of important information into the JobDetail object.


class Job extends Task {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");

String jobId;
boolean transacted;
JobDetails detail;
boolean persisted = true;

public Job(long when, String jobId, boolean transacted, JobDetails jobDetail) {
super(when);
this.jobId = jobId;
this.detail = jobDetail;
this.transacted = transacted;
}
....
}

Now, lets look at another type of Task, which is called SchedulerTask.


private abstract class SchedulerTask extends Task implements Runnable {
SchedulerTask(long schedDate) {
super(schedDate);
}
}

This is an abstract class, its subclasses are: LoadImmediateTask, UpgradeJobsTask, CheckStaleNodes.

To understand these tasks, it is better that we look at what SimpleScheduler class defined. In Ode, the job design was based around three time horizons: “immediate”, “near future”, and “everything else”.
Immediate jobs (i.e. jobs that are about to be up) are written to the database and kept in an in-memory priority queue. When they execute, they are removed from the database. Near future jobs are placed in the database and assigned to the current node, however they are not stored in
memory. Periodically jobs are “upgraded” from near-future to immediate status, at which point they get loaded into memory. Jobs that are further out in time, are placed in the database without a node identifer; when they are ready to be “upgraded” to near-future jobs they are assigned to one
of the known live nodes. recovery is straight forward, with stale node identifiers being reassigned to known good nodes.

In terms of time, we defined two variables, one is: _immediateInterval and _nearFutureInterval.
if a job’s scheduled date is between [now, now + _immediateInterval], it belongs to the “immediate” job.
while if it is in [now + _immediateInterval, now + _nearFutureInterval], it belongs to the “near future” job then.

You can check the SimpleScheduler.doLoadImmediate() and SimpleScheduler.doUpgrade() respectively for its logic.

Also, you may be aware that we’ve also had the CheckStaleNodes task, this is basically for clustering work, to
check if there are any stale nodes, if it has, we will move the assigned jobs over to other node by updating nodeId.

So now, we’ve seen different Tasks, like Jobs and SchedulerTask. Now, we will need an interface to run these Tasks, hence TaskRunner was introduced.


interface TaskRunner {
public void runTask(Task task);
}

Here is the implementation from SimpleScheduler.TaskRunner() method.


public void runTask(final Task task) {
if (task instanceof Job) {
Job job = (Job)task;
if( job.detail.getDetailsExt().get("runnable") != null ) {
runPolledRunnable(job);
} else {
runJob(job);
}
} else if (task instanceof SchedulerTask) {
_exec.submit(new Callable() {
public Void call() throws Exception {
try {
((SchedulerTask) task).run();
} catch (Exception ex) {
__log.error("Error during SchedulerTask execution", ex);
}
return null;
}
});
}
}

As I said before, once we’ve start BpelServer, we will start a thread running, it only gets stopped only when the BpelServer is been stopped.
Thats called SchedulerThread.

In this class, basically we had following members: PriorityBlockingQueue, this is queue for the immediate execution. TaskRunner, this is the
container for running Task. The logic for the running is quite straight forward.


/**
* Pop items off the todo queue, and send them to the task runner for processing.
*/
public void run() {
while (!_done) {
_lock.lock();
try {
long nextjob;
while ((nextjob = nextJobTime()) > 0 && !_done)
_activity.await(nextjob, TimeUnit.MILLISECONDS);

if (!_done && nextjob == 0) {
Task task = _todo.take();
_taskrunner.runTask(task);

}
} catch (InterruptedException ex) {
; // ignore
} finally {
_lock.unlock();
}
}
}

Now that we've seen all of important APIs here, we will look at how we start SimpleScheduler when ODEServer is started.
excerpt from SimpleScheduler.start() method.

public synchronized void start() {
if (_running)
return;

if (_exec == null)
_exec = Executors.newCachedThreadPool();

_todo.clearTasks(UpgradeJobsTask.class);
_todo.clearTasks(LoadImmediateTask.class);
_todo.clearTasks(CheckStaleNodes.class);
_processedSinceLastLoadTask.clear();
_outstandingJobs.clear();

_knownNodes.clear();

try {
execTransaction(new Callable() {

public Void call() throws Exception {
_knownNodes.addAll(_db.getNodeIds());
return null;
}

});
} catch (Exception ex) {
__log.error("Error retrieving node list.", ex);
throw new ContextException("Error retrieving node list.", ex);
}

long now = System.currentTimeMillis();

// Pretend we got a heartbeat...
for (String s : _knownNodes) _lastHeartBeat.put(s, now);

// schedule immediate job loading for now!
_todo.enqueue(new LoadImmediateTask(now));

// schedule check for stale nodes, make it random so that the nodes don't overlap.
_todo.enqueue(new CheckStaleNodes(now + randomMean(_staleInterval)));

// do the upgrade sometime (random) in the immediate interval.
_todo.enqueue(new UpgradeJobsTask(now + randomMean(_immediateInterval)));

_todo.start();
_running = true;
}

Also, please noted that we had two different types of JobProcessor, one is ordinary JobProcessor, the other one is PolledRunnableJobProcessor, which is meant for running some jobs that gets run periodically.

Categories: Java, ODE, Riftsaw

My Roadmap on Mac OS X

July 23, 2010 Leave a comment

Just like what I did for my fedora roadmap, here comes my Mac OS X one.

1. Instant message: Adium, http://adium.im/
2. video chat: skype, http://www.skype.com
3. irc client, colloquy, http://colloquy.info/
4. chinese input, just use the built-in one directly, here is an post about the chinese input, and also can use the chinese language for the whole mac osx. http://appleclinic.wordpress.com/2008/04/16/chinese-text-input/
5. firefox, In case you still like to use the firefox in your mac box, yes, it works great. http://www.firefox.com
6. twitter client, twitterrific: http://iconfactory.com/software/twitterrific
7. QQ, this one should be very china specific, :), good news is that we do have a Mac OS X QQ as beta right now.
8. QuickSilver, this is a new tool compared to what I had in both windows and linux, it makes people really easy to start application, you can download and install it from here. http://www.blacktree.com/
9. Textmate, this one is a lot of rubyists choice on doing ruby on rails.. http://macromates.com/, not free though.
10. Skitch, http://skitch.com/, make it easy to share screenshot etc.
11. Eclipse, this is still my preference for java programming.
12. Macports, this is a utility more like Fedora’s Yum, Ubuntu’s apt-get.
13. Growl, this is a great software for the notifications.
14. dropbox, this is a pretty good software if you want to sync stuff between mac and iphone.

If you want to install JDK5 in the snow leopard, here is a good solution to this problem, http://www.scribd.com/doc/22853741/Installing-Java-5-Back-on-Snow-Leopard, Here I’d like to thank Kurt, strong, liweinan for making some suggestions on these softwares. 😉

At last, this is what I had, http://skitch.com/jeffyu/dp3pm/fullscreen. 😉

please let me know what else you believe that I should try out.

Categories: Mac OS

Exploring ODE Part IV: BpelServer API

February 21, 2010 Leave a comment

If you look at the ODE source code, the BpelServer API is a very important one. In this entry, we will look at the class that how we use the BpelServer, for the ODE, lets look at the ODEServer source code.


__log.debug("Initializing transaction manager");
initTxMgr();
__log.debug("Creating data source.");
initDataSource();
__log.debug("Starting DAO.");
initDAO();
EndpointReferenceContextImpl eprContext = new EndpointReferenceContextImpl(this);
__log.debug("Initializing BPEL process store.");
initProcessStore(eprContext);
__log.debug("Initializing BPEL server.");
initBpelServer(eprContext);
__log.debug("Initializing HTTP connection manager");
initHttpConnectionManager();

// Register BPEL event listeners configured in axis2.properties file.
registerEventListeners();
registerMexInterceptors();
registerContextInterceptors();
.....

As above code shown:

  • Initialized the TransactionManager, which will be used in the datasource and scheduler service.
  • Created the data source.
  • Created the DAOConnectionFactory, the extension API is BpelDAOConnectionFactory.
  • Created the EndpointReferenceContext, which takes care of resolving EndpointReference.
  • Created the Process Store, it takes care of process deploying, undeploying, list etc.
  • Initializing the BpelServer, includes following actions: setMessageExchangeContext, setDaoConnectionFactory, setBindingContext, the BindingContext and the MessageExchangeContext are the extension points for communicating with partner services.
  • Register the EventListners, MexInterceptors etc, these are all the APIs in BpelServer.

You also could see how we initialize the BpelServer in the MockBpelServer class. In the Riftsaw project,it is in the BpelEngineImpl class. In the Riftsaw project, we are adding another implementation for the ProcessStore that leverages the JBoss Application Server’s Deployer mechanism, also we adding another implementation for the BindingContext that use the JAXWS based approach, which used the JBossWS to accomplish.

Categories: ODE, Riftsaw

Apache CXF Web Service Development book.

February 20, 2010 Leave a comment

I was invited to review the new book about Apache CXF from packtpub, it is called《Apache CXF Web Service Development》by Naveen Balani and Rajeev Hathi. From the table of content, it covers both web service and restful service in CXF, also had three chapters for the CXF’s frontend, transport, interceptors, invoke etc, which are the essential concepts of CXF’s architecture. So it definitely seems interesting to me. I will post more detailed review once I finished the book.

Categories: CXF, SOA

Exploring ODE Part III: architecture and modules introduction

January 30, 2010 Leave a comment

In this blog entry, we will continue to explore the ODE source code. Typically, we should see the ODE’s architecture in our first part of this series, but here I put it in the third part, as at that time, I was just trying to write a blog entry about the ODE’s inner model about bpel file, didn’t thought I will write this as a series.

Anyway, lets see the ODE’s architecture diagram, which I copied it from the ODE’s architecture wiki page.

On our first part, we look at the bpel compiler module, and we look at the JACOB framework on our second part.

In this part, we will try to make an introduction to ODE’s modules:

ODE core modules
1.bpel-api: It contains the api definition for ODE, some important packages are:

  • org.apache.ode.bpel.iapi: this is for integration interfaces, like Axis2 module will implement it.
  • org.apache.ode.bpel.rapi: these interfaces are for runtime api that are implemented in the bpel-runtime module.
  • org.apache.ode.bpel.pmapi: this is for the process management.
  • org.apache.ode.bpel.evt: this is for the event.

2. bpel-runtimes: this module takes care of implementing the Bpel’s Activities, like INVOKE, REPLY, WAIT by extending the JacobRunnable Object, also it is the place that includes the internal model for compiled Bpel file, and Channel definition. You would notice that it has v1 and v2 packages, thats for ODE 1.x and ODE 2.x respectively.
3. bpel-dao: this module is the API for DAO layer, currently, it doesn’t include the DAO API for process store.
4. dao-jpa: currently it is the openjpa implementation for DAO.
5. dao-jpa-db: This is the DDL script for openjpa’s impl.
6. dao-hibernate, dao-hibernate-db: these two are the Hibernate’s impl for DAO, and its DDL scripts.
7. bpel-schemas: this is module that use xmlbeans to generate Java objects from xsd schemas, they are: deploymentDescriptor, (dd.xsd), pmapi.xsd (Process Management API), schedules.xsd, context.xsd.
8. bpel-scripts: this module is having those bpel files, it is used in bpel-compiler’s test case.
9. bpel-compiler: this module is to convert the bpel file into ODE internal model for compiled bpel file.
10. il-common: this module is the common integration layer.
11. scheduler-simple: this module is the implementation of scheduler service.
12. bpel-store: this is the module takes charge of storing process from the filesystem, the artifact includes deploy.xml, .bpel, wsdl artifacts.
13. engine: this is the ode engine that uses the runtimes, dao, scheduler services.
14. bpel-ql: bpel query language.

JACOB framework module
1. jacob-ap
2. jacob

Integration modules:
1.axis2 integration: axis2, axis2-war
2.jca integration: bpel-api-jca, bpel-connector, jca-ra, jca-server
3.jbi integration: jbi
4.extension: extensions

some leftover modules are:
1. tools: this is for the bpelc, sendsoap command line.
2. utils: utils for ODE project.
3. tasks: this is tasks for buildr tool.
4. distro: this is the module for building distro.

Categories: BPEL, ODE, Riftsaw

Exploring ODE Part II: JACOB Framework

January 27, 2010 Leave a comment

In this blog entry, we will look at the ODE’s jacob framework, which is of a library taking care of concurrency processing. ODE use this lib underlying to solve the concurrency problem, ODE has a very good wiki explains about this framework, but here I would like to highlight some concepts and introduce a simple example in the end.

Firstly, I am reusing the wiki page’s example. Say we have a following process.

1.invoke
2.receive
3.wait
4.invoke

and we have 2 parallel execution of the process, without Jacob framework the execution would be:

1. Invoke1
2. Receive1
3. Wait1
4. Invoke1
5. Invoke2
6. Receive2
7. Wait2
8. Invoke2

so the above is totally sequentially, no concurrency at all. With the jacob framework, we might see following execution order.

1. Invoke1
5. Invoke2
2. Receive1
3. Wait1
6. Receive2
7. Wait2
4. Invoke1
8. Invoke2

From a client standpoint, we’ve achieved concurrency of execution even with one thread.

Now, we will see following concepts in jacob:

1. JacobRunnable, JacobObject
In the wiki page, the JacobRunnable, JacobObject is described as a simple closure. Just like above example shows, here we abstract the action like ‘Invoke, Receive’ etc as a JacobRunnable object. Personally I also see JacobRunnable as a command pattern, which implements the run method.

2. Channel
Once we have had the JacobRunnable object, how do we connect two JacobRunnable objects? in other words, how do we invoke the wait activity after the invoke in our above example. Here is where Channel comes to play, its function is to build connections between JacobRunnable. The Channel implementation is used JDK’s dynamic proxy, you can see it from ChannelFactory.

3. ChannelListener
In the wiki page, it is referred as MLs (MethodList), but I’d prefer to call it as Listener. With introduction of Channel object, we are able to pass the Channel object into our next activity or child activity, but we need to have a listener mechanism for the parent activity so that once the child activity finished, it is able to get notified and continues the flow.

4. @ChannelType annotion
In the Jacob, we are using the ‘@ChannelType’ annotation to generate the Channel and ChannelListener interfaces in the compile time.

5. JacobVPU, ExecutionQueueImpl
As wiki page said, here are the responsibilities of JacboVPU and ExecutionQueueImpl.
1) JacobVPU is the place of Jacob processing.
2) ExecutionQueueImpl is the container for all artifacts (mostly channels and reactions) managed by JacobVPU.
3) JacobVPU is also responsible for persisting its internal state, like serialize or de-serialize the object.
4) Continuations (and hence JacobRunnables) don’t “stay” in the VPU queues. They just get popped, executed and that’s it.

Now, I will introduce an example that works with Jacob API to accomplish the above example. we are having three JacobObjects(Continuation), they are INVOKE, RECEIVE, WAIT. But for the simplicity purpose, I will just have INVOKE and RECEIVE. Also we will add a channel for their communication, I called it Demo, here is the code for Demo Channel.

@ChannelType
public interface Demo {
public void onSuccess(String successInfo);
public void onFailure(String errorString);
}

as you read from the code, we are having two methods, one for successful case, the other is for failure. use either the maven tool or buildr, you would see the generated classes for this interface, they are DemoChannel and DemoChannelListener.

Next, we will see actions.

static class INVOKE extends JacobRunnable {
private DemoChannel _channel;

public INVOKE(DemoChannel channel) {
_channel = channel;
}

@Override
public void run() {
System.out.println("INVOKE Activity");

DemoChannel demoChannel2 = newChannel(DemoChannel.class, "demo2");
instance(new RECIEVE(demoChannel2));
object(new DemoChannelListener(demoChannel2) {
public void onSuccess(String successInfo) {
System.out.println(successInfo);
_channel.onSuccess("INVOKE Done...");
}

public void onFailure(String errorString) {
System.out.println(errorString);
}
});

}
}

static class RECIEVE extends JacobRunnable {
private DemoChannel _demoChannel;

public RECIEVE(DemoChannel demoChannel) {
_demoChannel = demoChannel;
}

@Override
public void run() {
System.out.println("Receive Activity");
_demoChannel.onSuccess("RECEIVE success...");
}
}

For this example, I will add another action to start our process, it is called Process.

static class Process extends JacobRunnable {

@Override
public void run() {
DemoChannel channel = newChannel(DemoChannel.class, "demo");
instance(new INVOKE(channel));
object(new DemoChannelListener(channel) {
public void onSuccess(String successInfo) {
System.out.println(successInfo);
System.out.println("Process Done");
}

public void onFailure(String errorString) {
System.out.println(errorString);
}
});
}

}

We will talk from Process class, basically, we’ve created a DemoChannel, and then we use ‘instance(…)’ method to add the ‘activity/JacobRunnable’ into the queue, use the ‘object(….)’ to define a listener for that channel.
In the INVOKE class, we’ve created a child activity that is called RECEIVE. Which puts RECEIVE class as part of INVOKE class. I know this is a bad example, it would be much better if I use a composite activity, like While or Sequence, but you know I am just being lazy. 😉

At last, we will use following code to execute this example:

public static void main(String[] args) throws Exception {
ExecutionQueueImpl soup = new ExecutionQueueImpl(null);
JacobVPU vpu = new JacobVPU(soup, new Process());

while(vpu.execute()) {
}

}

Run this method, you would get following output.

INVOKE Activity
Receive Activity
RECEIVE success...
INVOKE Done...
Process Done

If you want to look at the code by yourself, it lies in the ode-jacob module, it extends the ode-jacob-ap module. Below are some classes that you’d look into. CommSend, CommRecv. Jacob wraps the JacobRunnable as CommSend, wraps the ChannelListener as CommRecv. And then uses the CommGroup to do the match.ExecutionQueueImpl is the container for Continuation, ExecutionObject, Channel etc. In the ExecutionQueueImpl class, you would find couple static classes, like ChannelFrame, MessageFrame… these classes are mostly used for serialized and de-serialized the object.

Categories: BPEL, ODE, Riftsaw

Exploring ODE Part I: Bpel Compiler and its internal model.

January 26, 2010 Leave a comment

In the Apache ODE, it has a bpelc, bpelc.bat script for you to compile the bpel file into ODE specific format file. We can use this tool to verify whether the bpel file’s semantic is correct or not.

So in this blog entry, we will take a closer look at the architecture of this tool, (also known as bpel-compiler module). The ode-tool module is just a wrapper for bpel-compiler module.

Firstly, lets look at the bpel object model for BPEL file, it is known as ‘bom’ (bpel object model, I guess) in the source file. It put all of bpel object model into this package, and its base class is BpelObject, this base class extends the sourceLocation which is for keeping detail info of original bpel file. some known subclasses are: IfActivity, PartnerLink, PartnerLinkType, SequenceActivity etc. These subclasses share one feature, their constructor parameter type is Element.

Second concept here is called ActivityGenerator, as name implied, it is taking care of generating the Activities, like IfActivity, InvokeActivity, SequenceActivity.

The other concept is called OBase, this class is a base class for compiled bpel object, the known subclasses are: OAssign, OInvoke, which both extend from OActivity, others are like: OPartnerlink, OProperty..

So in the bpel-compiler module, the work procedure is convert the bpel file into BOM, and then using AcitivityGenerator to convert them into OBase (ODE inner Object model).

If you want to look at the source code, you can start with BpelC class, the method for it is called compile(File file), in this method, you would find it uses the BpelObjectFactory to convert the xml file into BOM, and then get the correct BpelCompiler implementation to convert the BOM object to compiled object representation. (objects extends OBase class).

In the bpel-compiler module’s test part, we are using the bpel files that are put in the bpel-scripts module, to do the unit test. If you want to learn about the bpel’s activity, this is also a good resource.

Categories: BPEL, ODE, Riftsaw

Maven Global Excludes tip.

January 22, 2010 Leave a comment

If you work on a project that has ton of jar dependencies, and you want to exclude the ‘xerces’ (for example), you might end up using the exclusion multiple times, as a lot of jars are depending on the ‘xerces’. In this case, you can use following way to achieve the ‘global exclude’ in maven.

Categories: Maven