Custom jndi object factory in wildfly 8 for CDI - mongodb

I am trying to achieve injecting a jndi resource using CDI for wildfly 8.
For this purpose i want to use a custom jnidfactory as developed in https://github.com/juanlmelo/mongo-jndi-plugin/
The problem is due to my limited knowledge in wildfly, I don't know the following.
1) how to activate/attach this jndifactory in wildfly, ofcourse I can create an object while startup and assign a jndi name to it programmatically , but want to explore custom factory feature of wildfly
2) the best practice to set the uri property needed by the object factory, i assume using System.getProperty inside the factory should suffice , as the DB uri will be different for each installation
once this is achieved I am confident I can get it injected into my classes using cdi.
I have tried my best to look for similar post, but couldn't find any, if you think this is duplicate please point me to the correct one.
Thanks,

If you want add custom JNDI factory to wildfly using https://github.com/juanlmelo/mongo-jndi-plugin/ you need to do few things:
1) You need to change a little bit implementation of https://github.com/juanlmelo/mongo-jndi-plugin/blob/master/src/main/java/com/mongodb/jndi/MongoClientJNDIFactory.java
- line 38 change to:
String mongoURI = (String) environment.get(MONGO_CLIENT_URI);
and comment out or delete lines 39-49
2) then run command mvn clean package and create directory eg.:
wildfly-8.1.0.Final/modules/com/mongodb/jndi/main/
copy there mongo-jndi-plugin-1.0.jar and create there module.xml file with content:
<?xml version="1.0" ?>
<module xmlns="urn:jboss:module:1.1" name="com.mongodb.jndi">
<resources>
<resource-root path="mongo-jndi-plugin-1.0.jar"/>
</resources>
<dependencies>
<module name="com.mongodb.driver"/>
<module name="javax.api"/>
</dependencies>
</module>
3) add mongo driver
-create directory: wildfly-8.1.0.Final/modules/com/mongodb/driver/main
-create there file: module.xml and place there:
<?xml version="1.0" ?>
<module xmlns="urn:jboss:module:1.1" name="com.mongodb.driver">
<resources>
<resource-root path="mongo-java-driver-2.11.0.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
</dependencies>
</module>
-add to this directory mongo-java-driver-2.11.0.jar library
4) add something like this
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<bindings>
<object-factory name="java:global/MongoClient" module="com.mongodb.jndi" class="com.mongodb.jndi.MongoClientJNDIFactory">
<environment>
<property name="mongoClientURI" value="mongodb://username:password#yourdomain.com:27017,username:password#yourdomain.com:27017"/>
</environment>
</object-factory>
</bindings>
<remote-naming/>
</subsystem>
to your domain.xml or standalone.xml
voilà
After this steps you can inject MongoClient into your classes using #Resource annotation (eg. #Resource(lookup = "java:global/MongoClient"

Related

wildfly custom module: unable to use class inside deployed EAR

I am creating a custom realm in wildfly that will be use by my application for login purposes. If I use the class inside a jar file of a global module, wildfly can find it. However, if I try pointing it to a class inside my EAR file, then wildfly cannot locate the class.
Below config is working. VersaCustomRealm class is located inside VRCustomRealm.jar
standalone.xml
<custom-realm name="vr-login-realm" module="micropact.login" class-name="com.versa.login.VersaCustomRealm">
<configuration>
<property name="admin" value="welcome"/>
</configuration>
</custom-realm>
module.xml
<?xml version='1.0' encoding='UTF-8'?>
<module xmlns="urn:jboss:module:1.1" name="micropact.login">
<resources>
<resource-root path="VRCustomRealm.jar"/>
</resources>
<dependencies>
<module name="org.wildfly.security.elytron"/>
</dependencies>
</module>
Below config does not work. What am I missing? What would be the correct module name for deployed EAR?
<configuration>
<property name="admin" value="welcome"/>
</configuration>
Older version of wildfly still supports login-module where you can specify the custom code. In the below example, I use VersaCustomRealm which is a class inside my EAR file and not in the global module. How can accomplish this with custom realm?
<security-domain name="vr-domain" cache-type="default">
<authentication>
<login-module code="com.versasys.licenseEase.jbosssx.VersaCustomRealm" flag="required">
</login-module>
</authentication>
</security-domain>
I don't believe you can. The server needs anything listed in standalone from modules, before the deployment scanner starts

Adding smallrye mutiny dependency in JBoss EAP 7.3

I have a microprofile application using Smallrye Mutiny, which I need to deploy on JBoss EAP 7.3. I have applied JBoss EAP XP patch to enable microprofile features. I have also added mutiny jar as a module in EAP.
Below are the module file contents
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1"
name="io.smallrye.reactive.mutiny">
<resources>
<resource-root path="mutiny-0.9.0.jar" />
</resources>
<dependencies>
<module name="org.reactivestreams" />
</dependencies>
</module>
And the module.xml for reactivestreams is
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.reactivestreams">
<resources>
<resource-root path="reactive-streams-1.0.3.jar" />
</resources>
</module>
However in my application I'm getting the below Exception
Failed to define class io.smallrye.mutiny.Multi in Module "deployment.SampleReactive.war" from Service Module Loader: java.lang.NoClassDefFoundError: Failed to link io/smallrye/mutiny/Multi (Module "deployment.SampleReactive.war" from Service Module Loader): org/reactivestreams/Publisher
How can I configure JBoss EAP to work with reactive applications built using Microprofile? Any help is appreciated.
Edit: I have managed to get the app working on EAP 7.3. But now I am facing a different issue.
App has REST Apis which emit Uni and Multi. The REST API produces Json. But when I run this program in EAP, I see and object as the response instead of a JSON.
It seems that EAP is not able to convert Uni and Multi to JSON.
Is there any library that I need to add for this to work?

Migration to JBoss7.2eap from jboss5.1.2eap : java.lang.NoClassDefFoundError: Lorg/apache/commons/dbcp/BasicDataSource

I have migrated my application from jboss5.1.2-eap to jboss-7.2-eapand java6 to java8 but after migration it is starting giving me exception while starting the server.
Caused by: java.lang.NoClassDefFoundError: Lorg/apache/commons/dbcp/BasicDataSource
we have a datasource.xml file present in the classpath of the server, having the following line of code.
<bean id="beanName" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="maxActive" value="10"/>
Also we have commons-dbcp-1.2.2.jar present in the classpath but it is not working for jboss-7.2-eap.
Now I am not sure if commons-dbcp-1.2.2.jar is supported by jboss7-eap. as it is present in the classpath of the application(present in the loaded module), but still spring is not able to create the bean for datasource.
I suppose that datasource in Jboss EAP should be placed in standalone.xml configuration file and looks like here:
<datasource jndi-name="java:jboss/datasources/Altis" pool-name="Altis" enabled="true">
<connection-url>jdbc:oracle:thin:#255.255.255.255:1521:sid</connection-url>
<driver-class>oracle.jdbc.OracleDriver</driver-class>
<driver>oracle</driver>
<security>
<user-name>username</user-name>
<password>passwd</password>
</security>
</datasource>
Given module information in the jboss-deployment-structure.xml inside the WEB-INF directory of the war file.
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="com.oracle.sql" export="true"/>
<module name="org.apache.commons.dbcp" export="true"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
Also the module directories should also follow the same naming convention as per the availability of your .class files inside the jar, like in my case I have created module org.apache.commons.dbcp as while opening commons-dbcp-1.2.2.jar file, .class files are present inside org/apache/commons/dbcp folder.
Note: In case of multiple modules, you need to identify there dependency if a module is dependent on other and that information will be given inside module.xml file. like
<module xmlns="urn:jboss:module:1.1" name="org.apache.commons.dbcp">
<resources>
<resource-root path="commons-dbcp-1.2.2.jar"/>
</resources>
<dependencies>
<module name="org.apache.commons.pool"/>
<module name="com.oracle.jdbc.driver"/>
</dependencies>
</module>

JBOSS CLI adding module with optional dependency

I have a module.xml that looks like:
<module xmlns="urn:jboss:module:1.1" name="com.oracle">
<resources>
<resource-root path="ojdbc6.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
<module name="javax.servlet.api" optional="true"/>
</dependencies>
Using JBOSS-CLI one can do this:
./jboss-cli.sh -c --command="module add --name=com.oracle --resources=<path-to-file>/ojdbc6.jar --dependencies=javax.api,javax.transaction.api,javax.servlet.api"
to deploy the module. It is almost the same exact thing and the module.xml is generated; so I need not keep track of another xml.
But how can I get the 'optional="true"' from JBOSS-CLI?
Version: JBOSS-EAP 6.2.0. (would be great if I can find a solution that would work for either jboss 6.x EAP and wildfly 8x).
The CLI module command appears to only support simple dependencies.
You could work around it by supplying a pre-generated modules.xml file and specifying it in the CLI command using
--module-xml=filepath_to_modules.xml

How to know Dependencies of a module/library(for e.g. EclipseLink) when configuring it in JBoss 7.1

I am a newbie to JBoss 7. Forgive me if some of my questions below does not make sense…
My question is not necessarily related to 'EclipseLink' but I am giving reference of below example just to those who also like me did not know that we have to configure our modules/libraries first.
I was running an example which makes use of EclipseLink JPA EntityManager on JBoss 7.1. I have also configured the JTA datasource(mysql) with the help of link( https://zorq.net/b/2011/07/12/adding-a-mysql-datasource-to-jboss-as-7/ ). My persistence.xml looks like as below...
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="CustomerDetailsPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:/mysql_customerdb</jta-data-source>
<class>com.springforbeginners.model.Customer</class>
</persistence-unit>
</persistence>
When I tried to run the example, I encounted with error(org.jboss.modules.ModuleNotFoundException: Module org.eclipse.persistence is not found). I searched over the net and got the link (http://mpashworth.wordpress.com/2012/01/25/configuring-eclipselink-2-3-1-in-jboss-7-1/). The link says that we have to first configure EclipseLink as a module in JBoss 7.1. This involves listing dependencies of our module(in this case 'EclipseLink') in a module.xml file which looks like below stored at path(jboss-as-7.1.1.Final\modules\org\eclipse\persistence\main)...
<?xml version="1.0" encoding="UTF-8"?>
<!-- Represents the EclipseLink 2.3.x module-->
<module xmlns="urn:jboss:module:1.1" name="org.eclipse.persistence">
<resources>
<resource-root path="eclipselink-2.3.0.jar"/>
</resources>
<dependencies>
<module name="asm.asm"/>
<module name="javax.api"/>
<module name="javax.persistence.api"/>
<module name="javax.transaction.api"/>
<module name="javax.validation.api"/>
<module name="javax.xml.bind.api"/>
<module name="org.antlr"/>
<module name="org.apache.ant"/>
<module name="org.apache.commons.collections"/>
<module name="org.dom4j"/>
<module name="org.javassist"/>
<module name="org.jboss.logging"/>
</dependencies>
</module>
We also have to place eclipselink-2.3.0 at the same path. I ran the example again to know that the error is resolved.
Why do we have to configure our libraries as modules?(as in earlier versions(JBoss 5.1) we just used to copy the jars in lib directory).
What I want to know is how do I know what are the dependencies that need to be listed in module.xml? The specified module.xml is working but I am still searching answer for my question? This is a general question and not just related to EclipseLink (as We may need to configure any other module in JBoss 7.1). Can anyone provide me a general pointer for knowing the dependencies for a module that we are going to configure with JBoss 7?
Thanking You in Advance.
Prakash