domingo, 13 de novembro de 2016

Importing Work Item Handlers in jBPM using a custom service repository

We previously talked about creating a custom Work Item Handler and how to import it in the jBPM designer. The process is not simple, it requires some manual steps and it is error prone - even some users had problems as you can see in the post comment's section.

jBPM 6.5 comes with a great new feature that makes easier to import services. In this post I will show you how to use this new feature.


A very simple Work Item Handler


Remember our hello world work item handler? Let's clone it and install it on your local maven using mvn clean install
Now create a directory on your installacation called repository. It should have a file with content "HelloWorld" and a child directory called HelloWorld. Inside this directory we should have a file named HelloWorld.wid with the following content:

[  [    "name" : "HelloWorld",    "description" : "Prints hello World in the console",    "displayName" : "Hello World!",    "defaultHandler" : "mvel: new org.jugvale.jbpm.workitemhandler.HelloWorkItemHandler()",    "mavenDependencies" : [          "org.jugvale.jbpm.workitemhandler:hello-workitemhandler:1.0"     ]  ]]


This file describes how jBPM can install your Work Item Handler, you can write it using JSON or MVEL(as above. A quick explanation about the fields can be found in JBPM documentation.
The final repository structure can be found below:




The next step is install this on jBPM and this can be done by using the sytem parameters org.jbpm.service.repository and org.jbpm.service.servicetasknames during jBPM startup:

./bin/standalone.sh -c standalone-full.xml -Dorg.jbpm.service.repository=file:///opt/repository -Dorg.jbpm.service.servicetasknames=HelloWorld

In this case you can choose what services you want to register using the system property org.jbpm.service.servicetasknames,  but you can't use "*". The property org.jbpm.service.repository accepts a URL and it can be a remote repository.

The other way is by opening the process designer and clicking on the yellow icon. Then you click on the "tool" icon and reopen the process designer and you should be able to see your service task available for use.


Notice also that it registers the Work Item Handler in the deployment descriptor as well and due JBPM-5411, be careful if you don't use a resolver for your WIH.

Conclusion


I created this post because the other one is outdated. We don't even use kmodule.xml anymore! However, the official documentation for this feature is real good!

sexta-feira, 11 de novembro de 2016

JBoss Modules with JavaFX


Anton Arhipov made a great post showing a Hello World app with JBoss modules. In his post comments, Ted Won created a "mavenized" version of his hello world. Since my friend Filipe Portes already made a great work by integrating JavaFX with OSGI, I decided to try jboss-modules 

In this post I simply used Ted's project with JavaFX(with some modifications) and it worked great!  


First obvious attempt:

  •  Clone Ted's project: 

git clone git@github.com:tedwon/hello-jboss-modules.git

  • Import his maven project on an IDE. I used Eclipe (File -> Import -> Existing Maven Project)


  • Let's develop now. Modify the Hello class to be a JavaFX application class:
  • Now build the project. Go back to the  hello directory in the command line and run mvn clean package
  • Once the project is built, copy the new hello jar to the modules directory: cp hello/target/hello.jar  mods/org/jbugkorea/hello/main/ 
  • Cool, but if you try to run now, you will have an exception:
Exception in thread "main" java.lang.NoClassDefFoundError: Failed to link org/jbugkorea/hello/Hello (Module "org.jbugkorea.hello:main" from local module loader @27ddd392 (finder: local module finder @19e1023e (roots: /opt/projects/hello-jboss-modules/mods))): javafx/application/Application at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:422) at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:446) at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:274) at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:78) at org.jboss.modules.Module.loadModuleClass(Module.java:606) at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190) at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363) at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351) at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93) at org.jbugkorea.app.Main.main(Main.java:7) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.jboss.modules.Module.run(Module.java:330) at org.jboss.modules.Main.main(Main.java:505)

Making it work


The reason why we have this error is because JavaFX is not on JDK classpath. What I am going to say on next steps is for jboss modules and JavaFX learning purposes, you must contact Oracle if you want to ship their JavaFX implementation.

An easier way to solve this is by creating a new module for jfxrt.jar:
  • Create a new directory for the JavaFX module, create a module.xml file and copy the jfxrt.jar to this directory. 
  • JavaFX depends on several JRE classes. I had to create a javax.api module from a Wildfly installation inside mods. I just copied it from a local wildfly installation: 
mkdir -p mods/javax/api/main/
cp /opt/jboss/WILDFLY/wildfly-8.2.0.Final/modules/system/layers/base/javax/api/main/module.xml mods/javax/api/main/
  • JavaFX make use of other internal sun libraries that are not included in javax.api module. You may add it at the end of javax.api modules.xml dependencies declaration:
                               
               
  • Now make hello dependent on JavaFX module and javaFX module dependent on javafx.api module. See below how your mods directory strucuture should look like:
  • Finally run and you should see JavaFX stage:

This is not a final application for JavaFX with JBoss modules because we may face other ClassNotFound or LinkageError during runtime and javax.api  will have to be adjusted in order to add the new dependencies. It was, however, a fun and useful hack to learn more about jboss modules.

terça-feira, 28 de junho de 2016

Hello World Wildfly Swarm 1.0 Final!


Today Wlidfly Swarm became 1.0 Final was announced! In my opinion, this is one of the most exciting Red Hat projects at the moment.

To celebrate this release, I made this quick video to the Generator tool.

Requirements:


  •  Java 8
  •  Maven 3


How to use:


  • Enter the group, artifact id and the APIs(dependencies) you want to use in the generator web page and click in "Generate Project"
  • Unzip the downloaded file and cd into the project directory
  • Run mvn widlfly-swarm:run
  • Use a browser to navigate to http://localhost:8080/rest/hello OR use the command curl http://localhost:8080/rest/hello
  • You should see the message "Hello from WildFly Swarm!";


Video



That's it, an 1 minute hello world! Now you can select the dependencies you need in your project before generating it and create your more advanced application.


domingo, 1 de maio de 2016

A CRUD using jBPM

Here's one interesting thing: everything gets better with jBPM. Even a CRUD (which does not exactly represent a business process) can be quickly created and you can have a much better overview of what's going on without having to read any line of code. In this post, I am going to show you a CRUD I created using the JPA Work Item Handler from my last post.

The CRUD business process

The CRUD actions are based on an Object of type Person created using the Data Modeller tool:


The object used in our CRUD. It was created using the data modeller

 The business process to create the CRUD make use of human tasks to get users input. A human task is responsible for creating an application menu for the user, the other tasks read users provided data. See the process diagram:

A jBPM CRUD Diagram

The box with text "Select Contact" is a reusable subprocess which goal is let users select one of the existing contacts (Person):
User can select a contact from the existing contacts
If you know BPMN, you might already understand how it works. There's no need to look any source code or read documentation, the diagram above tells you everything about the application.

Our process has variables to hold the users input. To pass information from users to the process, we must first understand how we can actually execute the process, and there are three ways:

  • Use the jBPM Console tool as the process executor engine. This way you can interact with the process using the console itself or the console remote APIs;
  • Create an application that use jBPM APIs to control the process execution using Java;
  • Use the new KIE Execution server. Recently it was added BPM capabilities to the server, so you can deploy your business process to it and control the execution using the KIE Server remote APIs.
Tasks and process can have HTML forms to take the user input or you can use a client application to interact with the server in order to pass parameters when starting process and when handling tasks. Now I see your surprise face: You don't  need to make any coding to create HTML forms for the process, you can generate a form for your task and process (jBPM Designer can generate it based on the task/process input) and then use the powerful jBPM forms tool to modify the form. Although you can customize the forms using Javascript and CSS,  no coding skill is required! See what it looks like:

Form for a task of our CRUD process
If you use the jbpm console itself as the process execution server, it will render the form for you when starting process and completing tasks, and you can even embed the form in an external web application!

Demo

The CRUD full project is also available in github, but here's a small video showing it in action with everything I described above: