Change the order in which bundles are deployed in JBOSS Fuse - apache-camel

I'm deploying my apache-camel project in JBOSS Fuse as a feature. Following karaf feature file is used for the project.
<?xml version="1.0" encoding="UTF-8"?>
<features name="${project.artifactId}-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
<feature name="${project.artifactId}" description="${project.description}" version="${project.version}">
...
<feature>camel-beanio</feature>
...
<bundle>mvn:${project.groupId}/abc-common/${common-version}</bundle>
<bundle>mvn:${project.groupId}/abc-service/${project.version}</bundle>
</feature>
</features>
When I install the main feature, it loads abc-service bundle before camel-beanio feature and the routes in abc-service which makes use of beanio dataformat fails.
I did some search on google and found options like, start-level, dependency, prerequesite ..etc. But, the currently configured name space is not permitting any of these attributes.
I also tried changing xml name space as provided in this example hosted on Github. But it was causing another error like
Caused by: java.lang.IllegalStateException: Could not find resource:
/org/apache/karaf/features/karaf-features-1.3.0.xsd
So, what could be rightway to ensure that camel-beanio feature is getting installed before actual service?

You should be able to write a feature file like this:
<features>
<feature name "nameOfYourProject">
<bundle dependency="true">mvn:org.apache.camel/camel-beanio/2.17.0</bundle>
..your abc bundle
..
</feature>
</features>
But I would probably advise you to create a folder called feature under /main and create a feature.xml. Manually edit that with your bundle dependencies such as:
<features>
<feature name="${project.artifactId}">
<bundle dependency="true">mvn:org.apache.camel/camel-core/2.17.0</bundle>
<bundle dependency="true">mvn:org.apache.camel/camel-blueprint/2.17.0</bundle>
<bundle dependency="true">mvn:org.apache.camel/camel-rabbitmq/2.17.0</bundle>
<bundle dependency="true">mvn:org.apache.camel/camel-jackson/2.17.0</bundle>
<bundle dependency="true">mvn:org.apache.commons/commons-lang3/3.4</bundle>
<bundle dependency="true">mvn:commons-codec/commons-codec/1.10</bundle>
<bundle dependency="true">wrap:mvn:org.apache.axis/axis/1.4</bundle>
<bundle dependency="true">wrap:mvn:org.apache.axis/axis-jaxrpc/1.4</bundle>
<bundle dependency="true">wrap:mvn:org.apache.axis/axis-saaj/1.4</bundle>
<bundle dependency="true">wrap:mvn:axis/axis-wsdl4j/1.5.1</bundle>
<bundle dependency="true">wrap:mvn:commons-discovery/commons-discovery/0.4</bundle>
<bundle dependency="true">wrap:mvn:javax.xml/jaxrpc-api/1.1</bundle>
<bundle dependency="true">mvn:org.slf4j/slf4j-api/1.7.13</bundle>
<bundle dependency="true">mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
</feature>
</features>
Add this to your plugin section in your pom:
<!-- to generate the karaf feature file from feature template file -->
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
<version>4.0.2</version>
<configuration>
<aggregateFeatures>false</aggregateFeatures>
<includeTransitiveDependency>false</includeTransitiveDependency>
<addBundlesToPrimaryFeature>true</addBundlesToPrimaryFeature>
<addTransitiveFeatures>false</addTransitiveFeatures>
</configuration>
<executions>
<execution>
<id>plugin-feature</id>
<goals>
<goal>features-generate-descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
Then when you run clean install the feature file will be generated in your target folder.

Related

Apache Karaf feature offline issue

In karaf org.apache.karaf.features.cfg file
I have added
featuresRepositories=mvn:org.apache.cxf.karaf/apache-cxf/3.0.8/xml/features
featuresBoot = cxf-jaxws
The cxf feature could fetch and be installed when karaf started with the connection.
But it will fail without connection, how can I pre-install cxf feature?
This is likely far from most optimal solution for this (would love to hear about the better ones) but you could create offline-repository project using karaf-feature-archetype and configure karaf-maven-plugin use something like following configuration:
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
<configuration>
<startLevel>50</startLevel>
<aggregateFeatures>true</aggregateFeatures>
<checkDependencyChange>true</checkDependencyChange>
<failOnDependencyChange>false</failOnDependencyChange>
<logDependencyChanges>true</logDependencyChanges>
<overwriteChangedDependencies>true</overwriteChangedDependencies>
</configuration>
<executions>
<execution>
<id>features-add-to-repo</id>
<phase>generate-resources</phase>
<goals>
<goal>features-add-to-repository</goal>
</goals>
<configuration>
<descriptors>
<!-- Feature repository paths -->
<descriptor>mvn:groupId/artifactId/version/xml/features</descriptor>
</descriptors>
<features>
<!-- features and their artifacts + dependencies to add to offline repository-->
<feature>featureName</feature>
<feature>featureName/version</feature>
</features>
<repository>target/offline-repository</repository>
</configuration>
</execution>
</executions>
</plugin>
When packaging the project i.e with command maven clean install (in environment with online access) it'll generate offline-repository under target folder which you can copy to your offline environment and tell karaf to use it by adding it to org.ops4j.pax.url.mvn.defaultRepositories in file org.ops4j.pax.url.mvn.cfg i.e file:${user.home}/offline-repository#snapshots#id=local if its located in home directory.
features.xml itself can be empty this is just to use karaf-maven-plugin not to create an actual feature repository.
Just be careful if you need to create a new version of the offline-repository to replace the old one. If the new version is missing any of the artifacts that are currently installed to karaf it can cause issues when trying to remove/uninstall them.

How to add a custom module in Wildfly Swarm when executing from custom main()

I have a custom Wildfly module for logging in Json format, which my Swarm application references in standalone.xml:
<subsystem xmlns="urn:jboss:domain:logging:3.0">
<console-handler name="CONSOLE">
<level name="INFO" />
<formatter>
<named-formatter name="json-formatter" />
</formatter>
</console-handler>
...
<formatter name="json-formatter">
<custom-formatter module="my.package.jsonLogFormatter" class="my.package.jsonLogFormatter.JsonFormatter"/>
</formatter>
</subsystem>
The module is saved in a Maven repository, from which it is copied during the Maven build to the target/classes folder.
The Maven wildfly-swarm-plugin then adds the module to the uberjar:
<plugin>
<groupId>org.wildfly.swarm</groupId>
<artifactId>wildfly-swarm-plugin</artifactId>
<version>2017.7.0</version>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
<configuration>
<additionalModules>
<additionalModule>jsonLogFormatter-1.2</additionalModule>
</additionalModules>
</configuration>
</plugin>
This works as expected when executing from the uberjar.
However, when running a custom main() class directly from the IDE, there seems to be no way to tell Swarm to use this module:
public static void main(String... args) throws Exception {
new org.wildfly.swarm.Swarm()
//.customModule("path/to/module") // <- doesn't exist
.start()
.deploy();
}
Swarm shows this error during startup:
Failed to load module "my.package.jsonLogFormatter" for formatter "json-formatter"

Appengine Maven Plugin - Endpoints Goal - Enable filtering on .discovery files

Following this guide, I implemented the Google Cloud Endpoints in my Maven project
Here is the properties of my pom.xml
<properties>
<appengine.app.id>xxxxxxxx</appengine.app.id>
</properties>
Here is my maven-war-plugin configuration in pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<!-- http://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html -->
<!-- To prevent corrupting your binary files when filtering is enabled, you can configure a list of file extensions that will not be filtered. -->
<nonFilteredFileExtensions>
<nonFilteredFileExtension>p12</nonFilteredFileExtension>
</nonFilteredFileExtensions>
<archiveClasses>true</archiveClasses>
<!-- https://cloud.google.com/appengine/docs/java/tools/maven#cloud_endpoints_goals -->
<webXml>${project.build.directory}/generated-sources/appengine-endpoints/WEB-INF/web.xml</webXml>
<webResources>
<!-- in order to interpolate version from pom into appengine-web.xml -->
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resource>
<resource>
<directory>${project.build.directory}/generated-sources/appengine-endpoints</directory>
<includes>
<include>WEB-INF/*.discovery</include>
<include>WEB-INF/*.api</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
Here is the head of my appengine-web.xml file
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>${appengine.app.id}</application>
<version>${project.version}</version>
....
</appengine-web-app>
Here is the generated data
The problem
the .discovery files does not resolve the maven property during their creation
mystore-v1-rest.discovery
"protocol": "rest",
"baseUrl": "https://${appengine.app.id}.appspot.com/_ah/api/mystore/v1/",
"basePath": "/_ah/api/mystore/v1/",
"rootUrl": "https://${appengine.app.id}.appspot.com/_ah/api/",
"servicePath": "mystore/v1/",
mystore-v1-rpc.discovery
protocol": "rpc",
"rootUrl": "https://${appengine.app.id}.appspot.com/_ah/api/",
"rpcUrl": "https://${appengine.app.id}.appspot.com/_ah/api/rpc",
"rpcPath": "/_ah/api/rpc",
Why this files are not filtered like any other file saved in the WEB-INF folder?
I use the Maven variables in many files (under the WEB-INF parent folder) and the values are replaced w/o problems.
How can i adjust my configuration to allow the filtering also on the .discovery files?
I think that (during the lib generation) the application value from the appengine-web.xml is taken without resolving the value and, during the Maven build, the filtering is not applied.
I already tried to add <filtering>true</filtering> to the resource configuration, w/o success
--- EDIT 25/01/2014 ---
After some received suggestions, I need to clarify a thing that I forgot to write in the original post.
The problem is related to the endpoints_get_discovery_doc
Here is the log of the Maven Goal
API Discovery Document written to ..\target\generated-sources\appengine-endpoints\WEB-INF/mystore-v3-rpc.discovery
API Discovery Document written to ..\target\generated-sources\appengine-endpoints\WEB-INF/mystore-androidtest-rpc.discovery
The file \target\generated-sources\appengine-endpoints\WEB-INF/mystore-v3-rpc.discovery is generated by the endpoints goal and it is not filtered.
Even with the filtering property
<resource>
<directory>${project.build.directory}/generated-sources/appengine-endpoints</directory>
<filtering>true</filtering>
<includes>
<include>WEB-INF/*.discovery</include>
<include>WEB-INF/*.api</include>
</includes>
</resource>
The generated files are not filtered.
Maybe the problem is that if the files are directly written in the ${project.build.directory}/generated-sources/appengine-endpoints folder, the files are not filtered?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webXml>${project.build.directory}/generated-sources/appengine-endpoints/WEB-INF/web.xml</webXml>
<webResources>
<!-- in order to interpolate version from pom into appengine-web.xml -->
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resource>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>${project.build.directory}/generated-sources/appengine-endpoints</directory>
<!-- the list has a default value of ** -->
<includes>
<include>WEB-INF/*.discovery</include>
<include>WEB-INF/*.api</include>
</includes>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>
<!--User the below Line, I also had the same problem that I solved using Note: <version>${app.version}</version><appId>${app.id}</appId> folow as per your configuration --!>
<plugin>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>${appengine.version}</version>
<configuration>
<enableJarClasses>false</enableJarClasses>
<version>${app.version}</version>
<appId>${app.id}</appId>
<!-- Comment in the below snippet to bind to all IPs instead of just localhost -->
<address>0.0.0.0</address>
<port>8080</port>
<!-- Comment in the below snippet to enable local debugging with a remote debugger
like those included with Eclipse or IntelliJ -->
<jvmFlags>
<jvmFlag>-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n</jvmFlag>
</jvmFlags>
</configuration>
<executions>
<execution>
<goals>
<goal>endpoints_get_discovery_doc</goal>
</goals>
</execution>
</executions>
</plugin>

WebApp Unable to find type, How to compile source into target dir

Basically I'm having to 2 maven modules and one should start the application by inherit the client source from the other one (because the client includes the EntryPoint).
Therefore I have 2 .gwt.xml files and to pom.xml files.
gwt.gwt.xml
<module>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User' />
<inherits name='org.fusesource.restygwt.RestyGWT' />
<!--Specify the app entry point class. -->
<entry-point class='com.myapp.admin.client.EntryPoint'/>
<source path='client'/>
<source path='rest'/>
<source path='consts'/>
</module>
web.gwt.xml
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User' />
<inherits name='com.myapp.admin.gwt' />
POM client (gwt), packaging: jar
<plugins>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
POM web, packaging: war
<!-- GWT Maven Plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<!-- Copy static web files before executing gwt:run -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
</plugin>
plus it includes a dependency with the gwt-module <classifier>sources</classifier>. I can compile my application without errors but I cannot run it because
[ERROR] [web] - Unable to find type 'com.myapp.admin.client.EntryPoint'
[ERROR] [web] - Hint: Check that the type name 'com.myapp.admin.client.EntryPoint' is really what you meant
[ERROR] [web] - Hint: Check that your classpath includes all required source roots
Which is reasonable because there is no source in the directory. but why is there no source ?
thanks for any help.
When using M2Eclipse with "resolve dependencies from the workspace", dependencies with a type different from jar (e.g. java-source) or a classifier all resolve to the target/classes of the Eclipse project, so you don't actually get the sources in your classpath.
AFAIK, Google Plugin for Eclipse takes the classpath from M2Eclipse, so you won't have the sources there. You need to edit the launch configuration to add the source directories (src/main/java and possibly others) of the projects you depend on to the classpath.

Maven Properties Plugin - doesn't work in inheritance

I have this directory structure
root
|- pom.xml
|- submodule1
|- pom.xml
|- project.properties
|- subsubmodules
|-pom.xml
Submodule1 inherits from root and subsubmodules inherit from submodule1
Subsubmodules has dependencies that uses properties from submodule1's project.properties to have define its version.
ie in Subsubmodules
<dependency>
<groupId>some.org</groupId>
<artifactId>someartifact</artifactId>
<version>${themodules.version}</version>
</dependency>
In project.properties of Submodule1, I have
themodules.version = 1.0
So I used the properties-maven-plugin by defining it in the root pom.xml
<project>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<!-- *edited from earlier post <file>etc/config/dev.properties</file>-->
<file>${basedir}/project.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Then I run mvn install at root level. Maven says it can't resolve ${themodules.version} in dependencies.
I also ran mvn install at the submodule level and it still can't resolve.
Help pls
Had a similar problem with code another developer checked in.
They had the properties-maven-plugin under the root pom.xml.
I moved it out to each subproject that consumed the properties, and made it path relative.
Since the main pom is in ${project.basedir}, the subproject will be in ../${project.basedir}.
That is, I added the plugin to the plugins element in those poms, and set the file element to ${project.basedir}/../default-pom.properties.
When I did that, it worked.
Nothing to do with inheritance here, you just need add location of your project.properties to properties-maven-plugin's configuration in your root pom.xml:
<configuration>
<files>
<file>etc/config/dev.properties</file>
<file>${project.basedir}/submodule1/project.properties</file>
</files>
</configuration>
Then do mvn clean install at root level.

Resources