About Apache Maven
Apache Maven is a distributed build automation tool used in Java application development to build and manage software projects. Apart from building, publishing, and deploying capabilities, using Maven for your {PRODUCT_DM} and {PRODUCT_BA} projects ensures the following:
-
The build process is easy and a uniform build system is implemented across projects.
-
All of the required JAR files for a project are made available at compile time.
-
A proper project structure is configured.
-
Dependencies and versions are well managed.
-
No need for additional build processing, as Maven builds output into a number of predefined types, such as JAR and WAR
Maven repositories
Maven uses repositories to store Java libraries, plug-ins, and other build artifacts. These repositories can be local or remote. {PRODUCT_DM} and {PRODUCT_BA} products maintain local and remote maven repositories that you can add to your project for accessing the rules, processes, events, and other project dependencies. You must configure Maven to use these repositories and the Maven Central Repository to provide correct build functionality.
When building projects and archetypes, Maven dynamically retrieves Java libraries and Maven plug-ins from local or remote repositories. Doing so promotes sharing and reuse of dependencies across projects.
Using the Maven Repository in your project
You can direct Maven to use the {EAP_LONG} Maven repository in your project in one of the following ways:
-
Configure the Project Object Model (POM) file (
pom.xml
). -
Modify the Maven settings file (
settings.xml
).
The recommended approach is to direct Maven to use the {EAP_LONG} Maven repository across all projects by using the Maven global or user settings.
From version 6.1.0 onwards, {PRODUCT_BA} and {PRODUCT_DM} are designed to be used in combination with Red Hat JBoss Middleware Maven Repository and Maven Central repository as dependency sources. Ensure that both repositories are available for project builds.
Configuring Maven using the project configuration file (pom.xml
)
To use Maven for building and managing your {PRODUCT_DM} and {PRODUCT_BA} projects, you must configure your projects to be built with Maven. To do so, Maven provides the POM file (pom.xml
) that holds configuration details for your project.
pom.xml
is an XML file that contains information about the project (such as project name, version, description, developers, mailing list, and license), and build details (such as dependencies, location of the source, test, target directories, repositories, and plug-ins).
When you generate a Maven project, a pom.xml
file is automatically generated. You can edit pom.xml
to add more dependencies and new repositories. Maven downloads all of the JAR files and the dependent JAR files from the Maven repository when you compile and package your project.
Find the schema for the pom.xml
file at http://maven.apache.org/maven-v4_0_0.xsd.
For more information about POM files, see Apache Maven Project POM Reference.
Configure Maven using the settings file
The Maven settings file (settings.xml
) is used to configure Maven execution. You can locate this file in the following locations:
-
In the Maven install directory at
$M2_HOME/conf/settings.xml
. These settings are called global settings. -
In the user’s install directory at
$USER_HOME/.m2/settings.xml
. These settings are called user settings. -
A custom location specified by the system property
kie.maven.settings.custom
.
Note
|
The settings used is a merge of the files located in these locations. |
The following is an example of a Maven settings.xml
file. Note the activeByDefault
tag, which specifies the default profile. In the following example, it is a profile with a remote Maven repository.
<settings>
<profiles>
<profile>
<id>my-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>fusesource</id>
<url>http://repo.fusesource.com/nexus/content/groups/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
...
</repositories>
</profile>
</profiles>
...
</settings>
Managing Maven dependencies
In order to use the correct Maven dependencies in your {PRODUCT} project, you must add relevant Bill Of Materials (BOM) files to the project’s pom.xml
file. Adding the BOM files ensures that the correct versions of transitive dependencies from the provided Maven repositories are included in the project.
See the {URL_INSTALLATION_GUIDE}#supported_comps[Supported Component Versions] chapter of {INSTALLATION_GUIDE} to view the supported BOM components.
-
Declare the BOM in
pom.xml
. For example:Example 1. BOM for Red Hat JBoss BPM Suite {PRODUCT_VERSION}.0<dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.bom.brms</groupId> <artifactId>jboss-brms-bpmsuite-platform-bom</artifactId> <version>6.4.2.GA-redhat-2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- Your dependencies --> </dependencies>
To check the current BOM version, see the {URL_INSTALLATION_GUIDE}#supported_comps[Supported Component Versions] chapter of {INSTALLATION_GUIDE}.
-
Declare dependencies needed for your project in the
dependencies
tag.-
For a basic {PRODUCT_BA} project, declare the following dependencies:
Embedded jBPM Engine Dependencies<dependency> <groupId>org.jbpm</groupId> <artifactId>jbpm-kie-services</artifactId> </dependency> <!-- Dependency needed for default WorkItemHandler implementations. --> <dependency> <groupId>org.jbpm</groupId> <artifactId>jbpm-workitems</artifactId> </dependency> <!-- Logging dependency. You can use any logging framework compatible with slf4j. --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> <dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> </dependency>
-
For a {PRODUCT_BA} project that uses CDI, declare the following dependencies:
CDI-Enabled jBPM Engine dependencies<dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> </dependency> <dependency> <groupId>org.jbpm</groupId> <artifactId>jbpm-kie-services</artifactId> </dependency> <dependency> <groupId>org.jbpm</groupId> <artifactId>jbpm-services-cdi</artifactId> </dependency>
-
For a basic {PRODUCT_DM} project, declare the following dependencies:
Embedded Drools Engine Dependencies<dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> </dependency> <!-- Dependency for persistence support. --> <dependency> <groupId>org.drools</groupId> <artifactId>drools-persistence-jpa</artifactId> </dependency> <!-- Dependencies for decision tables, templates, and scorecards. For other assets, declare org.drools:drools-workbench-models-* dependencies. --> <dependency> <groupId>org.drools</groupId> <artifactId>drools-decisiontables</artifactId> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-templates</artifactId> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-scorecards</artifactId> </dependency> <!-- Dependency for loading KJARs from a Maven repository using KieScanner. --> <dependency> <groupId>org.kie</groupId> <artifactId>kie-ci</artifactId> </dependency> <!-- Dependency for loading KJARs from a Maven repository using KieScanner in an OSGi environment. --> <dependency> <groupId>org.kie</groupId> <artifactId>kie-ci-osgi</artifactId> </dependency> <dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> </dependency>
Do not use both
kie-ci
andkie-ci-osgi
in onepom.xml
file.-
To use the {KIE_SERVER}, declare the following dependencies:
Client Application {KIE_SERVER} Dependencies<dependency> <groupId>org.kie.server</groupId> <artifactId>kie-server-client</artifactId> </dependency> <dependency> <groupId>org.kie.server</groupId> <artifactId>kie-server-api</artifactId> </dependency> <!-- Dependency for Red Hat JBoss BRMS functionality. --> <dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> </dependency> <dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> </dependency>
-
To create a remote client for {PRODUCT_BA} or {PRODUCT_DM}, declare the following dependencies:
Client Dependencies<dependency> <groupId>org.kie.remote</groupId> <artifactId>kie-remote-client</artifactId> </dependency>
-
To use assets in
KJAR
packaging, the recommended way is to includekie-maven-plugin
:Kie Maven Plugin<!-- BOM does not resolve plugin versioning. Consult section Supported Components of Red Hat JBoss BPM Suite Installation Guide for newest version number. --> <packaging>kjar</packaging> <build> <plugins> <plugin> <groupId>org.kie</groupId> <artifactId>kie-maven-plugin</artifactId> <version>6.5.0.Final-redhat-7</version> <extensions>true</extensions> </plugin> </plugins> </build>
-
-
Declare the following dependencies to testing purposes:
<!-- JUnit dependency --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- Red Hat JBoss BPM Suite integration services dependency --> <dependency> <groupId>org.jbpm</groupId> <artifactId>jbpm-shared-services</artifactId> <classifier>btm</classifier> <scope>test</scope> </dependency> <!-- Logging dependency --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> <scope>test</scope> </dependency> <!-- Persistence tests dependencies --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.core.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>${h2.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.codehaus.btm</groupId> <artifactId>btm</artifactId> <version>${btm.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> </dependency>
Alternatively, for extensive testing of {PRODUCT}, include the
jbpm-test
dependency:<dependency> <groupId>org.jbpm</groupId> <artifactId>jbpm-test</artifactId> </dependency>
Note that
jbpm-test
includes some of the previous dependencies, for example thejunit
dependency, dependencies required for persistence tests, and others.To include the
jbpm-test
dependency as part of your KJAR, set the dependency scope toprovided
. Doing so ensures that the dependency is available at runtime, thereby avoiding unresolved dependency errors. The recommended practice is to use only business resources in your KJAR and not includejbpm-test
dependency in it. It is a best practice to keep the test suite for the KJAR in a separate project.
Note
|
If you are deploying {PRODUCT_DM} or {PRODUCT_BA} on Red Hat JBoss EAP 7, you must make changes to the project BOM files. For more information about the BOM changes, see the Red Hat JBoss EAP Migration chapter in the {MIGRATION_GUIDE}. For more information on BOM usage in Red Hat JBoss EAP 7, see the Using Maven with JBoss EAP chapter in the Red Hat JBoss EAP Development Guide. |
Integrated Maven Dependencies
Throughout the documentation, various code samples are presented with KIE API for the release version. These code samples require Maven dependencies in the various pom.xml
file, for example:
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1-redhat-2</version>
<scope>compile</scope>
</dependency>
Red Hat JBoss-related product dependencies can be found at the following location: Red Hat Maven Repository.
Uploading artifacts to the Maven repository
There may be scenarios when your project may fail to fetch dependencies from a remote repository configured in its pom.xml
. In such cases, you can programmatically upload dependencies to {PRODUCT} by uploading artifacts to the embedded maven repository through {CENTRAL}. {PRODUCT} uses a servlet for the maven repository interactions. This servlet processes a GET request to download an artifact and a POST request to upload one. You can leverage the servlet’s POST request to upload an artifact to the repository using REST. To do this, implement the HTTP basic authentication and issue an HTTP POST request in the following format:
PROTOCOL://HOST_NAME:PORT/CONTEXT_ROOT/maven2/[GROUP_ID replacing '.' with '/']/ARTIFACT_ID/VERSION/ARTIFACT_ID-VERSION.jar
For example, to upload the org.slf4j:slf4j-api:1.7.7.jar
, where ARTIFACT_ID
is slf4j-api
, GROUP_ID
is slf4j
, and VERSION
is 1.7.7
, the URI must be:
http://localhost:8080/business-central/maven2/org/slf4j/slf4j-api/1.7.7/slf4j-api-1.7.7.jar
The following example illustrates uploading a JAR located at /tmp
directory as a user bpmsAdmin
with the password abcd1234!
, to an instance of {PRODUCT} running locally:
package com.rhc.example;
import java.io.File;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UploadMavenArtifact {
private static final Logger LOG = LoggerFactory.getLogger(UploadMavenArtifact.class);
public static void main(String[] args) {
// Maven coordinates:
String groupId = "com.rhc.example";
String artifactId = "bpms-upload-jar";
String version = "1.0.0-SNAPSHOT";
// File to upload:
File file = new File("/tmp/" + artifactId + "-" + version + ".jar");
// Server properties:
String protocol = "http";
String hostname = "localhost";
Integer port = 8080;
String username = "bpmsAdmin";
String password = "abcd1234!";
// Create the HttpEntity (body of our POST):
FileBody fileBody = new FileBody(file);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart("upfile", fileBody);
HttpEntity entity = builder.build();
// Calculate the endpoint from the Maven coordinates:
String resource = "/business-central/maven2/" + groupId.replace('.', '/') + "/" + artifactId +"/" + version + "/" + artifactId + "-" + version + ".jar";
LOG.info("POST " + hostname + ":" + port + resource);
// Set up HttpClient to use Basic pre-emptive authentication with the provided credentials:
HttpHost target = new HttpHost(hostname, port, protocol);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(target.getHostName(), target.getPort()),
new UsernamePasswordCredentials(username,password));
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
HttpPost httpPost = new HttpPost(resource);
httpPost.setEntity(entity);
AuthCache authCache = new BasicAuthCache();
BasicScheme basicAuth = new BasicScheme();
authCache.put(target, basicAuth);
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);
try {
// Perform the HTTP POST:
CloseableHttpResponse response = httpclient.execute(target, httpPost, localContext);
LOG.info(response.toString());
// Now check your artifact repository!
} catch (ClientProtocolException e) {
LOG.error("Protocol Error", e);
throw new RuntimeException(e);
} catch (IOException e) {
LOG.error("IOException while getting response", e);
throw new RuntimeException(e);
}
}
}
Alternative Maven Approach
An alternative Maven approach is to configure your projects pom.xml
by adding the repository as shown below:
<distributionManagement>
<repository>
<id>guvnor-m2-repo</id>
<name>maven repo</name>
<url>http://localhost:8080/business-central/maven2/</url>
<layout>default</layout>
</repository>
</distributionManagement>
Once you specify the repository information in the pom.xml
, add the corresponding configuration in settings.xml
as shown below:
<server>
<id>guvnor-m2-repo</id>
<username>bpmsAdmin</username>
<password>abcd1234!</password>
<configuration>
<wagonProvider>httpclient</wagonProvider>
<httpConfiguration>
<all>
<usePreemptive>true</usePreemptive>
</all>
</httpConfiguration>
</configuration>
</server>
Now when you run the mvn deploy
command, the JAR file gets uploaded.
Deploying {PRODUCT} Artifacts to Red Hat JBoss Fuse
Red Hat JBoss Fuse is an open source Enterprise Service Bus (ESB) with an elastic footprint and is based on Apache Karaf. The {PRODUCT_VERSION} version of {PRODUCT} supports deployment of runtime artifacts to Fuse.
With {PRODUCT} 6.1 or better, {PRODUCT} runtime components (in the form of JARs) are OSGi enabled. The runtime engines JARs MANIFEST.MF
files describe their dependencies, among other things. You can plug these JARs directly into an OSGi environment, like Fuse.
Warning
|
POM Parser Limitations in OSGi Environments
{PRODUCT} uses a scanner to enable continuous integration, resolution, and fetching of artifacts from remote Maven repositories. This scanner, called KIE-CI, uses a native Maven parser called Plexus to parse Maven POMs. However, this parser is not OSGi compatible and fails to instantiate in an OSGi environment. KIE-CI automatically switches to a simpler POM parser called The |
Separating Assets and Code
One of the main advantage of deploying {PRODUCT} artifacts on Red Hat JBoss Fuse is that each bundle is isolated, running in its own classloader. This allows you to separate the logic (code) from the assets. Business users can produce and change the rules and processes (assets) and package them in their own bundle, keeping them separate from the project bundle (code), created by the developer team. Assets can be updated without needing to change the project code.