How to add a module programmatically in Wildfly? - java

In Wildfly-CLI jboss-cli.shit is possible to add a module like this
module add --name=org.postgres
--resources=postgresql-42.2.5.jar
--dependencies=javax.api,javax.transaction.api
This adds the file postgresql-42.2.5.jar and creates module.xml with the following structure in /modules/org/postgres/main:
<?xml version='1.0' encoding='UTF-8'?>
<module xmlns="urn:jboss:module:1.1" name="org.postgres">
<resources>
<resource-root path="postgresql-42.5.1.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
How can this be done programmatically with ModelControllerClient (available in org.wildfly.core:wildfly-controller-client:19.0.1.Final)?
ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getByName("localhost"), 9990);

It cannot be done with the ModelControllerClient. The module command is a high level CLI command and not what is referred to as an operation.
You could launch a CLI process and send the command. The other option would be to copy the JAR and create the module.xml programmatically.

Related

java.lang.NoClassDefFoundError: javax/net/ssl/HostnameVerifier

I am trying to execute rest api using HTTP client in java
I am using ant project so using below dependencies in module.xml
<module xmlns="urn:jboss:module:1.3" name="kv.http-client">
<resources>
<resource-root path="httpcore-4.4.14.jar"/>
<resource-root path="httpclient-4.5.13.jar"/>
</resources>
</module>
While executing the code I am getting below error. Please let me know what is wrong with this.
java.lang.NoClassDefFoundError: javax/net/ssl/HostnameVerifier
at org.apache.http.impl.client.HttpClients.createDefault(HttpClients.java:56)
As this thread from JBoss community suggests, you should add a dependency to the javax.api package:
You should be able to fix this by adding
<module name="javax.api"/>
to the dependecies section of the module.xml for the module
org.apache.commons.httpclient

How to resolve resource-root path for jboss-deployment-structure inside the docker

I have a jar which can't be copied to ear while generating docker-image. Also, I can't add the jars as modules because of some dependency issue.
So, I have added below resource-root in my jboss-deployment-structure file(To make it same as copying the jar in the EAR's lib directory).
false
<!-- This corresponds to the top level deployment. For a war this is the war's module, for an ear -->
<!-- This is the top level ear module, which contains all the classes in the EAR's lib folder -->
<deployment>
<!-- exclude-subsystem prevents a subsystems deployment unit processors running on a deployment -->
<!-- which gives basically the same effect as removing the subsystem, but it only affects single deployment -->
<exclude-subsystems>
<subsystem name="jpa"/>
</exclude-subsystems>
<dependencies>
<module name="org.abc" services="import"/>
<module name="org.abcde.zye" optional="true"/>
</dependencies>
<resources>
<!-- These add additional classes to the module. In this case it is the same as including the jar in the EAR's lib directory -->
<resource-root path="/../../../standalone/outsideEar/outside-abc.jar"/>
</resources>
</deployment>
<sub-deployment name="abc-abc.war">
<dependencies>
<module name="org.abcde.zye" optional="true"/>
</dependencies>
</sub-deployment>
<sub-deployment name="abc-ejb.jar">
<dependencies>
<module name="org.abcde.zye" optional="true"/>
</dependencies>
</sub-deployment>
My Ear Structure:
my-ear.ear
|- lib
|- abc-abc.war
|- abc-ejb.jar
|- META-INF
|- application.xml
|- jboss-app.xml
|- jboss-deployment-structure.xml
|- maven
|- pom.properties
|- pom.xml
When I deploy this ear to wildfly-15.0.1.Final server outside the docker it works fine.
Path for resource-root is resolved, outside-abc.jar is copied to the below tmp folder (which is generated dynamically on server start) and I am able to perform operation by using classes of outside-abc.jar.
wildfly-15.0.1.Final\standalone\tmp\vfs\deployment\deploymentdc506469ec651715
wildfly-15.0.1.Final structure:
wildfly-15.0.1.Final
|- bin
|- domain
|- modules
|- standalone
|- outsideEar
<!-- This path is resolved with resource-root path="/../../../standalone/outsideEar/outside-abc.jar" -->
|- outside-abc.jar
|- configuration
|- data
|- deployments
|- my-ear.ear
|- lib
|- log
|- tmp
|-jboss-modules.jar
One More case which works fine: If I use below resource-root then my jar should be inside bin folder as wildfly-15.0.1.Final/bin/outsideEar/outside-abc.jar
<resource-root path="../../outsideEar/outside-abc.jar"/>
Docker configuration:
If I use same above structure, build docker image and start container for the image. It is not able to identify the jar file and do not copy it to
wildfly-15.0.1.Final\standalone\tmp\vfs\deployment\deploymentdc506469ec651715 folder which eventually causes ClassNotFoundException while performing operations.
I have verified that outside-abc.jar is properly copied to the mounted docker directory(Already added configuration in docker-compose file).
I have been further inside of this and found that a attribute use-physical-code-source="true" can be set for resource-root to resolve the path using physical source code location.
When use-physical-code-source="true" : It reads from physical location. I am not getting what is the actual physical location inside the docker. I think it is deployments folder or deployments/my-ear.ear/META-INF.
When use-physical-code-source="false"(default is false) : It reads from vfs directory(Inside temp).
I tried many different paths to make it work but, there was no luck.
Possible cases I tried:
<resource-root path="./../../../../../../../../outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../../../../../../outsideEar/outside-abc.jar"/>
<resource-root path="./../../../../../../../../../standalone/outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../../../../../../../standalone/outsideEar/outside-abc.jar"/>
<resource-root path="./../../../../../../../outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../../../../../outsideEar/outside-abc.jar"/>
<resource-root path="./../../../../../../../../standalone/outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../../../../../../standalone/outsideEar/outside-abc.jar"/>
<resource-root path="./../../../../../../outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../../../../outsideEar/outside-abc.jar"/>
<resource-root path="./../../../../../../../standalone/outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../../../../../standalone/outsideEar/outside-abc.jar"/>
<resource-root path="./../../../../../outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../../../outsideEar/outside-abc.jar"/>
<resource-root path="./../../../../../../standalone/outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../../../../standalone/outsideEar/outside-abc.jar"/>
<resource-root path="./../../../../outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../../outsideEar/outside-abc.jar"/>
<resource-root path="./../../../../../standalone/outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../../../standalone/outsideEar/outside-abc.jar"/>
<resource-root path="./../../../outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../outsideEar/outside-abc.jar"/>
<resource-root path="./../../../../standalone/outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../../standalone/outsideEar/outside-abc.jar"/>
<resource-root path="./../../outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../outsideEar/outside-abc.jar"/>
<resource-root path="./../../../standalone/outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../../standalone/outsideEar/outside-abc.jar"/>
<resource-root path="./../outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../outsideEar/outside-abc.jar"/>
<resource-root path="./../../standalone/outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../../standalone/outsideEar/outside-abc.jar"/>
<resource-root path="./outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./outsideEar/outside-abc.jar"/>
<resource-root path="./../standalone/outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./../standalone/outsideEar/outside-abc.jar"/>
<resource-root path="./standalone/outsideEar/outside-abc.jar" use-physical-code-source="true"/>
<resource-root path="./standalone/outsideEar/outside-abc.jar"/>
For above cases, I have mounted jars inside both bin and standalone folders as bin/outsideEar/outside-abc.jar and standalone/outsideEar/outside-abc.jar. So, I confirm jar is available to the docker wildlfy server.
Requirement summary:
How is resource-root path resolved(inside and outside docker) when
use-physical-code-source="true" and use-physical-code-source="false"?
Is there any way to pass only directory name for resource root so that
all the jars under that directory can be copied to tmp/deployment. If
not possible, then is there any way which can be applied to pass jar
name dynamically to the jboss-deployment-structure.xml using either properties file or environment variable so that at container start-up jar can be copied to the temp/deployment.
Any assistance you can provide would be greatly appreciated.
Thank you.

Use WildFly module both datasource and connectionFactory

I have a module in Wildfly to use as my datasource to Firebird. It works great
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="org.firebirdsql">
<resources>
<resource-root path="jaybird-2.2.13.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
<module name="javax.resource.api"/>
<module name="javax.xml.bind.api"/> <!-- Jaybird 3.0 onwards doesn't need this -->
<module name="org.antlr4"/>
</dependencies>
</module>
and the jar is put inside the directory of module.xml.
But I want to use the driver both with data source and also to create a pure JDBC connection in connectionfactory like Class.forName("org.firebirdsql.jdbc.FBDriver");, not using data source provided by the server.
If I put jaybird in pom.xml I got errors. I think because this is duplicating the libs. How can I solve this?
I just added the below code under <subsystem xmlns="urn:jboss:domain:ee:4.0">
<global-modules>
<module name="org.firebirdsql" slot="main"/>
</global-modules>
Thanks, Mark Rotteveel for answer on the Jaybird bug tracker.

ClassNotFoundException org.h2.Driver in Wildfly

I am trying to deploy and run my ear file in wildfly. when I try to access following code it gives ClassNotFoundException for org.h2.Driver.
String jdbcURL = "jdbc:h2:file;MODE=Derby;auto_server=true"; Class.forName("org.h2.Driver");
Connection = DriverManager.getConnection(jdbcURL, username", "password");
My module.xml
<module xmlns="urn:jboss:module:1.1" name="com.h2database.h2">
<resources>
<resource-root path="h2.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
<module name="javax.servlet.api" optional="true"/>
</dependencies>
</module>
is any I need to Change?
WildFly already ships with a module named com.h2database.h2. I don't think you need to add your own.
As for the ClassNotFoundException, make sure your deployment has a dependency on the module com.h2database.h2. There are several ways to add a dependency to your deployment the easiest probably being to add a Dependencies: com.h2database.h2 to your MANIFEST.MF. See the class loading documentation for other ways.

How to load dynamically a class with class.forName in JBOSS 7

I'm migrating my web application to JBOSS 7 and I have problems with the Class.forName method.
I have basically 2 jars, each one in one different module:
CampusComponentsJava-1.4.4.jar
CampusGateway-2.5.3-SNAPSHOT.jar
The code from CampusComponentsJava loads dynamically a class from CampusGateway-2.5.3-SNAPSHOT.jar
in the following way:
Class.forName("edu.uoc.campusgateway.osid.authentication.AuthenticationManager")
I have created 2 modules in the modules folder:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="edu.uoc.oki2">
<resources>
<resource-root path="CampusGateway-2.5.3-SNAPSHOT.jar" />
<resource-root path="CampusLauncherJava-1.1.3-SNAPSHOT-filter.jar"/>
<resource-root path="OkiBusJava-1.2.2-config-uoc.jar"/>
<resource-root path="OkiBusXmlSchemas-1.1.1-SNAPSHOT.jar"/>
<resource-root path="OkiOSID-2.0.jar"/>
<resource-root path="JavaUtils-1.1.2-SNAPSHOT.jar"/>
<resource-root path="LibTecsidel.jar"/>
</resources>
<dependencies>
</dependencies>
</module>
And
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="edu.uoc.okicomps">
<resources>
<resource-root path="CampusComponentsJava-1.4.4.jar"/>
<resource-root path="CampusComponentsJava-1.4.4-config-uoc.jar"/>
</resources>
<dependencies>
<module name="edu.uoc.oki2" export="true"/>
</dependencies>
</module>
I the later one the tag to express the idea that module edu.uoc.okicomps depends on module edu.uoc.oki2 since one jar of the edu.uoc.okicomps module wants to load dynamically a class from one jar of the module edu.uoc.oki2:
Finally, since the webapp needs all the jars I have declared explicitally access to both modules of the webapp in the META-INF/MANIFEST.xml
Manifest-Version: 1.0
Class-Path:
Dependencies: edu.uoc.okicomps,edu.uoc.oki2
However it is not working failing with the exception:
java.lang.NoClassDefFoundError: Could not initialize class edu.uoc.campusgateway.osid.authentication.AuthenticationManager
Any help would be apreciated!
Thank you very much in advance.
I found the problem. The problem was that the Class.forName, due to its own nature, executes static code and the constructor.
In this case, the static code tries to load through the classloader a property file that is included in another jar that I forgot to add. So the fix to my problem is:
1) add the following line to the module.xml
2) add physically the file CampusComponentsJava-1.4.4-config-uoc.jar to the
modules\edu\uoc\oki2\main folder

Categories

Resources