I have a question about dependencies in jboss modules.
I have a spring application with structure like:
myApp.war/
--/WEB-INF
--/classes/com/myapp/monitoring/IMonitoring.class
--/classes/com/myapp/monitoring/MonitoringFirst.class
--/lib
my-core.jar
IMonitoring.class defines contract for monitoring class
MonitoringFirst.class provides implementation for mornitoring, also it uses some class defined in my-core.jar for logging purpose so it depends on my-core.jarin spring I define bean like:
<bean id="myMonitoring" class="com.myapp.monitoring.MonitoringFirst">
then I decided to prepare another implementation of IMonitoring.class and provide it in sepatare jar as module in jboss modules so in jboss-deployment-structure.xml I have like:
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="com.myapp.my-customization" />
</dependencies>
</deployment>
</jboss-deployment-structure>
and my module defines jar with second implementation of IMonitoring.class inside
<module xmlns="urn:jboss:module:1.0" name="com.myapp.my-customization">
<resources>
<resource-root path="customization.jar"/>
</resources>
<dependencies>
<module name="my-core.jar"/>
</dependencies>
</module>
then in my spring I can use
<bean id="myMonitoring" class="com.myapp.monitoring.MonitoringSecond">
but since MonitoringSecond also uses some class defined in my-core.jar for logging purpose I had to move my-core.jar to jboss modules - otherwise class needed in MonitoringSecond.class is not available and I have java.lang.ClassNotFoundException: com.myapp.LogManager from [Module "com.myapp.my-customization:main" from local module loader....
Unfortunatelly class used for logging purpose (com.myapp.LogManager in my-core.jar) need information about name of the war in which it is called from, what can be achieved by asking for URL like
URL url = LogManager.class.getResource(LogManager.class.getSimpleName() + ".class");
but this gives different results:
when class is located in myApp.war/WEB-INF/lib it gives:
vfs:/C:/server/bin/content/myApp.war/WEB-INF/lib/my-core.jar/com/myapp/LogManager.class
and I can determine war name
when class is located in jboss module it gives:
jar:file:/C:/server/modules/system/layers/base/com/myapp/my-customization/main/my-core.jar!/com/myapp/LogManager.class
and here I don't have info about war name
Finally, actual question:
Is there possibility that MonitoringSecond class can use LogManager.class defined in /WEB-INF/lib so that I'm not forced to move my-core.jar to jboss modules ?
If not, some other idea to determine war name from which LogManager.class has been called ?
Hope I didn't confuse it too much.
Thanks for any answer. Regards.
A module in $JBOSS_HOME/modules is not possible to depend on a deployment WAR (Dynamic module). So It is not possible to maintain my-core.jar inside war lib folder, my-core.jar have to be located in $JBOSS_HOME/modules
Related
I'm trying to deploy my Spring-boot app to a wildlfy server.
However, i'm finding some conflicts between the libs.
So, i want my app to use only what i define on my pom, and completely ignore all wildfly modules.
Is it possible?
Using Wildfly 10 and spring-boot 2.x
Modules
Yes, it is possible. According to the RedHat docs, ยง3.4, and according to my practice which I have tested several times: You can PREVENT A Module being implicitly loaded. For this:
Create (if not already existing) jboss-deployment-structure.xml file and add this into that file:
<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="org.javassist" />
<module name="org.dom4j" />
<module name="org.apache.commons.configuration" />
<!--and so on.. -->
</exclusions>
</deployment>
</jboss-deployment-structure>
add this (jboss-deployment-structure.xml) file to the project (For a web application (WAR) add this file to the WEB-INF directory. For an EJB archive (JAR) add it to the META-INF directory).
Sub-systems
On the other hand, EAR files (modules) will most likely include sub-systems, like WAR and JAR files. You can exclude only sub-system, from the module, as well. For this, include this snippet in the same (jboss-deployment-structure.xml) file:
<exclude-subsystems>
<subsystem name="SUBSYSTEM_NAME" />
</exclude-subsystems>
In my project, there is Karaf feature XML file contains all OSGi bundles. Now, this is used as dependency in other maven project's pom.xml file.
<dependency>
<groupId>a.b.c</groupId>
<artifactId>dummyfeature</artifactId>
<type>xml</type>
<classifier>features</classifier>
<version>1.0.0</version>
</dependency>
Now, following code is being used to install above feature.
KarafDistributionOption.features(
maven()
.groupId("a.b.c")
.artifactId("dummyfeature")
.version("1.0.0")
.type("xml")
.classifier("features"), "dummyfeature")
Is there a way to exclude a particular OSGi bundle from above feature programtically?
https://issues.apache.org/jira/browse/KARAF-5376 provides a way to alter the features read from XML file. You can:
blacklist some bundles
blacklist some features
override some bundles (like changing version or even group/artifact IDs)
override entire features
See this comment for overview of the mechanism. There's no documentation fragment yet (I didn't have time to do it). But for your particular case, you should add etc/org.apache.karaf.features.xml file with this content:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Configuration generated by Karaf Assembly Builder
-->
<featuresProcessing xmlns="http://karaf.apache.org/xmlns/features-processing/v1.0.0">
<blacklistedBundles>
<!-- there are several patterns you can use here -->
<bundle>mvn:groupId/artifactId</bundle>
<bundle>mvn:groupId/artifactId/1.0</bundle>
<bundle>mvn:groupId/artifactId/[1,2)</bundle>
</blacklistedBundles>
</featuresProcessing>
In a Maven project, I can include the classes with no problem.
However, during the runtime, I get ClassNotFoundException when I try to create an instance of that class.
Part of the pom.xml file:
<dependency>
<groupId>acmeGamesGroupId</groupId>
<artifactId>acmegames</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${acmegameslibs}\acme-1.0.jar</systemPath>
</dependency>
Why can a class be found during compile-time, but not in the run-time? What do I need to do in the pom.xml file? help.
You need more info. What is your execution environment: native java, tomcat, what? But my guess is your app is delivered as a jar file.
Unexpectedly the Java class loader cannot find classes in embedded jar files
I have a spring integration project deployed in jboss as a WAR file.
The project uses maven and structured to support any type of archival War or Jar.
However, the dependencies of the project (all spring jars and custom jars) should be externalized
The reason would be that, later there would be 100s of Spring Integration flows would be deployed and if we have the jars in WEB-INF/libs the size of WAR grows to ~ 50MB. As we have abstracted much of our functionality in a seperate jar (would be added as dependency to my spring integration project), Externalization will result in reducing the WAR file to ~ 5 KB.
I do not have a web.xml and use the WebInitializer for loading the context (Which is part of my common functionality and added as dependency)
Below is what I have tried with JBOSS.
Created a module com.xxx.yyy and added all my spring/third party and custom jars as resources.
Added the dependency to manifest file. (This did not work)
Added the jboss-deployment-structure.xml to my war WEB-INF (did not work)
If I give the wrong module name its throws errors as module
not found.
The war gets deployed, but not initialized. If I have the dependencies in my WEB-INF/lib, everything works as expected.
Below is the jboss deployment structure xml that I used.
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
<deployment>
<dependencies>
<module name="com.xxx.yyy" services="import" >
<imports>
<include path="META-INF**"/>
<include path="org**"/>
</imports>
</module>
</dependencies>
</deployment>
</jboss-deployment-structure>
Here is the expectation,
Externalize the Jar dependencies.
Import the dependencies to my war(manifest or jboss-deployment-structure.xml)
Should be used Spring Service should be initialize.
The deployed war should be working as it does if the libraries are
in WEB-INF
Please help...
With JBOSS EAP 6, Its not possible to deploy the war without a web.xml, But such is possible only with tomcat or by using spring boot.
Also, to address this problem, we had to create a dummy web.xml and use jboss modules to load dependencies.
When building a jnlp with the maven-webstart-plugin, I found that the runtime dependencies weren't being included in the jnlp.
I'm using a template like this:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="$jnlpspec" codebase="${url}/${appName}" href="${outputFile}">
<information>
<title>${appName}</title>
<vendor>$project.Organization.Name</vendor>
<homepage href="${url}/${appName}"/>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se version="$j2seVersion"/>
$dependencies
</resources>
<application-desc main-class="${main}" />
</jnlp>
How can I include the runtime dependencies? Well, I can include them all individually:
<plugin>
<groupId>org.codehaus.mojo.webstart</groupId>
<artifactId>webstart-maven-plugin</artifactId>
<configuration>
<dependencies>
<includes>
<include>groupId:artifactId</include>
...
</includes>
</dependencies>
...
</configuration>
</plugin>
...but ideally, I don't want to have to remember to change this every time I add a runtime dependency to my project.
Is there a way to instruct the plugin to include all runtime dependencies?
So it turns out that the default is to include all compile and runtime dependencies.
What was going on?
Well, I'm also using ant to deploy the jnlp onto a server, and in the ant file, $dependencies was being set using mvn:dependencies without the scope being specified as runtime. So adding the scope changes the $dependencies fileset which is incorporated into the jnlp file.
I use a parent pom configuration where one of the modules is the web start project. I like to keep this as minimal as possible. I have compile dependencies only to a logging library, the main application module (another module in the same parent pom structure), and jar files including native binaries. In addition to these compile dependencies, I have some test dependencies and a system dependency to a local javaws.jar file.
It seems that the maven webstart plugin includes any runtime dependencies from modules which is included to the web start project as a compile dependency.
It might be a solution for you to split up your project in a similar manner.
Regarding the native binaries. I had to modify the velocity template somewhat to get these dependencies as nativelib instead of jar resources.