Wildfly Make a module depends of a EAR/WAR - module

I'm building a product that must be extended by external people of our organization, we don't want the war to be changed by the "external people".
So, our application has the following structure.
EAR
WAR
JAR A
JAR B
extension module defined in jboss-deployment-structure
The extension module is like this
<sub-deployment name="A.war">
<dependencies>
<module name="extension.module" optional="false">
</module>
</dependencies>
</sub-deployment>
We thought the "external people" could create the "extension.module" module and than add the behavior they want. But to do that they need to add dependencies to the JAR A and JAR B inside the war/ear.
Can you help me solving this?

Related

How do I tell Wildfly that I want to use the Wildfly module when deploying an EAR?

I'm using Wildfly 11 with Java 8. Previously I was building a WAR file, which required the dom4j JAR file. Rather than including it in the WAR's WEB-INF/lib directory, I linked to the Wildfly modules JAR by adding an entry in the WEB-INF/jboss-deployment-structure.xml. Now I want to package this WAR as part of an EAR. So I created a jboss-deploymebnt-structure.xml file at teh root of the EAR, with these lines
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<sub-deployment name="myapp.war">
<dependencies>
...
<module name="org.dom4j" />
Now when I deploy the EAR, the WAR is failing to deploy with errors like
service jboss.undertow.deployment.default-server.default-host./myapp: org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./orgsclient: java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [META-INF/spring/infrastructure.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/dom4j/io/STAXEventReader
What else do I need to do to tell the EAR file that the WAR is using the Wildly module dom4j as opposed to one I'm packaging with the EAR itself?
Check if your jboss-deploymebnt-structure.xml is correctly placed in META-INF subfolder (beside with application.xml) of your built ear package. If you're using maven ear plugin you should put the xml file in:
ear/src/main/application/META-INF/jboss-deploymebnt-structure.xml
Please note the application folder is default resource folder for ear plugin.
If you still have a problem with NoClassDefFound, try to redeclare the dependency as 'ear global' and set it as exported
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.dom4j" slot="main" export="true"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
If you still have a problem then declare the module as a global module in wildlfy config (under the ee subsystem). Then you can get rid off the the jboss deployment descriptor at all.
<subsystem xmlns="urn:jboss:domain:ee:4.0">
<global-modules>
<module name="org.dom4j">
</global-modules>
...

How can I use the external jars on JBoss 7?

Now I can load jars which is under the EAR/lib.
But I want to put the jars to a common path, for other application to use.
I found that jboss-deployment-structure.xml file's tag can do this.
But it doesn't work. I got the ClassNotFound exception.
I don't know why?
<deployment>
<resources>
<resource-root path="/common/test.jar" />
</resources>
</deployment>
One way of using global libraries in different applications can be reached by making them available as modules.
Therefor, extend the modules by the library you are providing as a server provider.
Example:
To make your test.jar available to all applications, create a folder with the modules name and a main subdirectory (e.g. modules/commons/test/main).
Place your library there and a module description file with the name module.xml.
Example content:
<module xmlns="urn:jboss:module:1.0" name="commons.test">
<resources>
<resource-root path="test.jar"/>
</resources>
</module>
Now the library is available to all applications.
To get access to the module, your application has to define the dependency in the manifest.
Applications MANIFEST.MF:
Dependencies: commons.test
This can be also done by maven during build time.
Check https://docs.jboss.org/author/display/AS7/Class+Loading+in+AS7 for details
Please note that you're modifying the server itself. All applications using your module are depending on it. A application with a dependency to the module commons.test wont be deployed on a server which does not have this module provided.

maven2 use libs in a specific folder during compilation

In my project structure there is a folder called /libs which contains all necessary libraries, that my project need during compilation. Is it possible that I told maven2 during the process of compilation to use these libraries instead of dependencies or smth. else?
So I call mvn compile war:war and after that my .war contains the libraries out of the /libs folder.
BR,
mybecks
I suppose you are looking for System Dependencies like
<project>
...
<dependencies>
<dependency>
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<version>2.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/foo-bar-2.0.0.jar</systemPath>
</dependency>
</dependencies>
...
</project>
System dependencies will not be copied into the war file - maybe you can achiev this by putting them into src/main/webapp/WEB-INF/lib directory instead of ${project.basedir}/libs.
DISCLAIMER: I just tried to answer the question and do not recommend the solution for all dependencies.

Activate profile in depended-on POM?

My company writes companion products for project management software that uses that software's Java API. They release new API versions with new releases of their products, and also point releases for bug fixes etc. We need to support clients using various versions of their software (and by extension, their API). In order to do this without unnecessary code duplication, we have defined profiles in our products that include the necessary dependencies for each API version.
I have a war project built using this technique with the "api70" profile activated, and another project that depends on that war project with a type of pom, in order to pull in the war's dependencies. The problem is that when building this second project, the profile-specific dependencies are not being included, even though I'm defining -Papi70 on the maven command line when building the depending project.
Is there any way to get this to work?
In the war project:
<!-- API 7.0 profile. -->
<profile>
<id>api70</id>
<dependencies>
<dependency>
<groupId>com.bigcompany</groupId>
<artifactId>integrationlibrary</artifactId>
<version>7.0-a</version>
</dependency>
</dependencies>
<properties>
<apiversion>api70</apiversion>
</properties>
</profile>
In the depending project:
<!-- Depend on war as type=pom for dependency mediation. -->
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>warproject</artifactId>
<version>${warVersion}</version>
<type>pom</type>
</dependency>
Command line used for building depending project:
mvn -P api70 clean package
The resulting build does not include integrationlibrary or any of its transitive dependencies.
I think that your problem doesn't apply to profiles at all. It's about how transitive dependencies work for war packaging. By design they doesn't work :) War archive contain its dependencies in WEB-INF/lib folder or if it is packaged in ear it can share libraries with ear libs. More of the problem you can read on this wiki article. It's about Skinny Wars but topic relates also your problem.
For you interesting is also this JIRA issue.
Quick but not elegant solution is to change packaging form war to pom (or create duplicate pom with pom packaging).
Why don't you create an api70-deps pom project and let your war and dependant project both pull that in, profile activated or otherwise?
This approach works wonders for me... my poms become so much more tidier.

Maven - add dependency on artifact source

I have two maven modules, one that ends up as a jar, and one war that depends on that jar.
I want the jar module to package it's source code together with the compiled classes in the jar, so that the second module is able to access it. I have tried using the maven-source-plugin, but I am confused as to how to add a dependency on the output of that. It seems that the dependency by default goes to the compiled jar, and not the source-code jar (ending with "-source.jar") that maven-source-plugin creates.
How do I add the "-source.jar" as a dependency, while still preserving the dependency on the compiled sources?
I've not tried this, but I think you need to create two profiles in your project. One which builds the main jar. The other which builds the sources jar. Unfortunately, I'm not exactly sure how you would build that profile. I couldn't find a good example of it so far.
(Accoding to the comments, you don't actually need a profile. You can just use the sources-plugin which will deploy the sources and make them available via the sources classifier)
In theory, you'd use the 2nd profile to attach the sources to the project. This creates a 2nd entry in your repository for the sources using that classifier. Once you install/deploy the sources to your repository, you should be able to include the sources as a dependency by using the classifier tag on the dependency to specify the sources directly.
So you'd have something like this in your webapp POM:
<dependencies>
<dependency>
<groupId>myGroup</groupId>
<artifactId>myJar</artifactId>
<version>4.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>myGroup</groupId>
<artifactId>myJar</artifactId>
<version>4.0</version>
<type>jar</type>
<classifier>sources</classifier>
</dependency>
</dependencies>
Did you try adding the src directory as a resource directory in the build section? That should copy the source into the jar on build.