Karaf Maven Tools performance issue in Eclipse IDE

If you develop karaf related bundles in Eclipse IDE or another Java IDE the common way is to create maven driven projects and let maven manage dependencies and build.

Since karaf 4.0 you need to use a special maven plugin to parse the classes to find and automatic register Services. The plugin is called ‘karaf-services-maven-plugin’ and is working for every build.

Eclipse is using ‘Maven Builder’ to organise and build java classes in the background. So you can see errors while you are working on the files and detect compile problems fast. Therefore the Maven Builder is called for every ‘Automatic Project Build’ e. g. if you save files, start Eclipse and start exports / maven builds.

I found that the performance of the automatic build rapide slow down if I start using the maven plugin. In fact every saving need 60 seconds. I have 48 maven related project in my workspace. Starting of eclipse keeps me from work for minimum 30 minutes!

Not very happy about this behaviour I was searching for solutions. I reduced the usage of the karaf plugin and switched off automatic project builds in eclipse and closed unused projects. But with the effect that code changes where no more be refactored thru the source code. Not the solution I wanted.

Yesterday I came back to this plage and started downloading the code, tracing the execution time and looking for the performance. I find out that the Apache ClassFinder is part of the problem. Calling it eats most of the time and I found that the plugin collects all the dependencies/artefacts to be parsed for by the ClassFinder.

The simplest way to reduce the runtime problem is to reduce the amount of parsed classes. So I just did it. I created a filter option for the collected artefacts and set the filter to the minimum amount of artefacts needed for the ClassFinder. Recommended are extended classes. To have a fast solution I created a fork of the karaf plugin and implemented my solution. Without using the filter it will work like before.

Use this plugin configuration:

  <plugin>
      <groupId>de.mhus.ports.karaf.tooling</groupId>
      <artifactId>karaf-services-maven-plugin</artifactId>
      <configuration>
        <artifactInclude>.*mhu.*</artifactInclude>
     </configuration>
  </plugin>

I marked the changes. To use it in eclipse you need to add the following plugin configuration:

<pluginManagement>
     <plugins>
           <plugin>
               <groupId>de.mhus.ports.karaf.tooling</groupId>
               <artifactId>karaf-services-maven-plugin</artifactId>
               <version>${karaf.tool.version}</version>
               <executions>
                   <execution>
                       <id>service-metadata-generate</id>
                       <phase>process-classes</phase>
                       <goals>
                           <goal>service-metadata-generate</goal>
                       </goals>
                  <configuration>
                    <artifactInclude>.*mhu.*</artifactInclude>
                  </configuration>
                   </execution>
               </executions>
          </plugin>
       </plugins>    
    </pluginManagement>

The configuration ‘artifactInclude’ contains a regular expression to filter the selected dependencies. You can see a list of all dependencies in the output of the plugin.

In this way I reduced the execution time from more then 60 seconds to around 3 seconds.

Problem solved!

Advertisements

Java: Find Method Reference Names

Since Java 8 it’s possible to use references to methods like it is in most other languages already standard. The notation is Class::MethodName, e.g. MyClass::myMethod

But the new Feature is not what it promise. The developer would expect to get a reference object like Method to work with the referenced method. But Java did not implement real References it packs the reference in a calling lambda expression. Something like (o) -> o.myMethod() and returns a reference to this lambda construct.

What a stupid behaviour!

In this way it’s not possible to get any information about the referenced method. Not the name or expected return type etc.

Short: The solution is to analyse the byte code and grab the method name out of it. Like it’s done here: https://github.com/mhus/mhus-lib/blob/master/mhu-lib-core/src/main/java/de/mhus/lib/core/util/lambda/LambdaUtil.java

Long:

Continue reading “Java: Find Method Reference Names”

How to order node children

Currently I store the child order information in the child properties. This means the child hold a ‘sort’ property which shows how to to sort this node into the list of children nodes.

This strategy shows a lot of problems. First of all if I try to change the order I have to change all child nodes. This could end in a access denied problem if I do not have access to one of the child nodes. Second if I move the child node a stare ‘sort’ parameter will maybe disturb the new order information.

Therefore the best and mostly not used strategy is to store the order information at the paren node. If you are able to write the parent node, you are able to reorder the children of the node. And you are not forced to change these ones.

I should implement it in cherry web soon in this way!

Cherry Portal First Success

To create a new portal framework is a long planed project for me. There are several reasons for it. Last I tried to use apache sing as a portal to use for own projects but finally I had to drop this idea. But I get a lot of impressions from different portal software I had already used and will try to bring the good together.

First try is out now. The last weeks I spent most time in specification. Specially how the http request and resource resolving should work to solve a wide range of requirements.

In the current version a demo application shows a simple website and if you have imagine you could see … what ever.

Have fun playing around with it … https://github.com/mhus/cherry-web

Resolving a Renderer

Resolving a renderer for a resource is not as simple as it seams. The team from apache sling shows me that the rendering is more complex and should be more then a simple content output.

In modern WCM a resource is an abstract thing containing more meta data then pure content. All the  meta data together brings a useful content to the user. And there are different ways to present it. Html is the visible presentation of the data. Json and xml are technical presentations needed to download data in the background. Sling shows that we can have different renderer for the same content. It depends on the current use case.

How to find the correct content renderer is an interesting question. Sling are using request parameters like ‘request method’ and parts of the requested path to find a resource. Parameters from the resource are linking to the correct script rendering the content (see this picture).

 

Bonita Sub-Processes

Playing around with Bonita sub-processes gave me a couple of interesting discoveries…

The first step was to create a sub-process by selecting tasks and using the context menu to create a new sub-process. A sub-process is a closed process connected to the main process by an interface.

But before a list of founding using the ‘create subprocess’ function.

  1. The new process lacks of a lane. It’s easy to create and you should do it to define a default actor.
  2. The new process lacks of a start and end point. It’s working without but for consistency and a defined flow you should create them.
  3. Every Task will be renamed to ‘Copy of ‘. That’s ugly.
  4. The ned process is disconnected from the main process. This means different variables. You need to map the in and out variable mapping to transfer date between the processes. This will not be done automatically after creating the sub-process. But it will be done at creation time. But the mapping is not correct at all.
    To fix the main-to-sub mapping change the mapping type from ‘Assigned to Contract Input’ to ‘Assigned to Data’.
    To create the sub-to-main mapping use the ‘Auto map’ button.
  5. Sub processes have a separated set of actors also. You need to map it separately.
  6. It’s not possible to stop the main process inside the sub-process. Every ‘end’ will jump back into the main process execution. This could be a problem if fatal errors occur inside the sub-process.

To use the interface between main and sub-process you can use the variables mapping as described below. For every new variable you need extend the mapping. But you are free to use the sub-process in different situations and map it with multiple data sets.

More interesting is the possibility to send errors to the calling process. Use the ‘end error’ endpoint and define a error code. Add the ‘catch error’ event at the ‘call activity’ and you can handle the error result of the sub-process. Important: No data will be transferred from sub to main process in case of an error.

You can use my example process to explore the behavior. Initial, Step1 to Step4 are the default flow. Steps 2 and 3 are part of the sub-process. Try setting of variable values thru the process. In Step3 you can choose the ‘Error’ button to provoke an error. Use it and you will recognize that the data will not be changed in the main process. Download!

Sub-processes are interesting to separate or to re-use parts of the main process. But the benefits are rare if the creation and maintenance process should be simple.

BPM Error Handling Best Practice

Creating Business Processes using a BPM (in my case Bonitasoft BPM) we had the problem to handle failures in the right way. In the first time we tried to catch all errors and handled them with a End/Terminate-Entity. Looking backward it was a odd way to process the exception states.

The focus should be by maintenance and at most by the customers using the system. Customers don’t want to reinitialize a process every time an error occurred. The want to maintainer to fixe it and let the process flow. Maintainer don’t want to have much work with processes running.

I should show two very common scenarios happen in the real life:

  1. All processes are based on tasks using operations working over the network. Maybe sending mails using a database etc. A lost of network connection (maybe only a segment) will cause a lot of tasks to fail and trigger the error handling.
  2. User is creating a process instance inserting data that’s simply wrong. But the data can only be validated later in the flow. For example a wrong customer or contract id.

The first case shows a technical problem. It should be fixed by the administrators and then the processes should be restarted and do the work. It’s a technical failure.

The second case shows a professional problem. We have the wrong information from the user. A task will fail and could not be done, even if it will be retried. In this case a task error handler trail must be followed. And important: There could occur different incidents.

To implement this concept we changed the definition of automatic tasks with connectors. A connector should throw an exception if something technical went wrong. This exception should the task force to change status to ‘failed’. In this case we can retry the task if the technical problem is solved.

Next we check the return values of the connector. If something professional went wrong the returned data should contain such a information, like “returncode=-5” or empty values “customerId=”. Small post processor scripts can check the data and fire errors handlers to  jump into another part of the process.

The following example shows the behavior. I used a manual task to insert the ‘returned data’

Bonita_BPM

and validate it with post processors

Bonita_BPM_Error_post

The processors are very simple, e.g ‘checkStatusNo’:

if (status.equals("no"))
  throw new Exception("status is no");

The ‘checkStatusError’ script will change the status of the task to ‘failed’. It’s the situation of a technical failure.

In this way processes are more robust, customers are more happy and visual representation is more clear. It’s a win-win situation 😉

Download the sample process.