JAX-RS 2.0 will not work on Weblogic 12.1.3. The default is 1.0 based on Jersey implementation.
I will post shortly the jars necessary to make it working. Some of the jars were modified by me.
Friday, 18 March 2016
Wednesday, 16 March 2016
JAX-RS 1.0 on Weblogic 12.1.3
Mind you that on Weblogic 12.1.3 only JAX-RS 1.0 will work. The implemention is 1.18.
To enable it, make sure to include in your web-app, the following weblogic.xml :
To enable it, make sure to include in your web-app, the following weblogic.xml :
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd">
<context-root>/webcontext</context-root>
<container-descriptor>
<prefer-web-inf-classes>true
</container-descriptor>
</weblogic-web-app>
If you deploy the application as an EAR, it is important to note that if you intend to package your applicaton as an EAR, you can only include one WAR, that is only one Jersey web-app will work, multiple ones will fail.
Friday, 19 February 2016
Create / replace datasource with WLST online mode
The following tutorial has been checked to work Webogic 12c version 12.1.3 and 12.2,1.
There are 3 steps involved:
1. Define a jython script to create a datasource
2. Define instance specific parameters
3. Execute the script
1. Create your jython script createDS.py:
####################################
def connectAdmin() :
try:
connect(adminServerUser,adminServerPassword, adminServer)
print('Successfully connected')
except:
print 'Unable to find admin server...'
exit()
def deleteDS() :
try:
cd('/SystemResources/' + dsName)
set('Targets',jarray.array([], ObjectName))
except:
print 'Datasource not created yet'
try:
cd('/JDBCSystemResources')
datasources = cmo.getJDBCSystemResources()
for datasource in datasources :
currentDSName = datasource.getName()
if dsName == currentDSName :
try:
datasource.forceShutDown()
except:
print 'Could not shutdown datasource'
try:
cmo.destroyJDBCSystemResource(datasource)
except:
print 'Could not destroy data source'
except:
print 'could not delete datasource'
def retrieveTargets() :
targetsNames = targets.split(" ")
targetsArray = jarray.zeros(len(targetsNames),ObjectName)
index = 0
for targetName in targetsNames :
targetsArray[index] = ObjectName('com.bea:Name='+targetName+',Type=Server')
index = index + 1
return targetsArray
if __name__== "main":
print('This will enable you to create or update a Datasource')
connectAdmin()
print('Starting a edit session')
edit()
startEdit()
deleteDS()
print 'Creating data source'
# Create a new Mbean ( a JDBC resource)
cd('/')
cmo.createJDBCSystemResource(dsName)
#Naming the datasource under JDBCSystemResources
cd('/JDBCSystemResources/' + dsName + '/JDBCResource/' + dsName)
cmo.setName(dsName)
print 'Assigning JNDI name'
#Setting JNDI name
cd('/JDBCSystemResources/'+dsName+'/JDBCResource/'+dsName+'/JDBCDataSourceParams/'+dsName)
set('JNDINames',jarray.array([String(jndiName)], String))
cd('/JDBCSystemResources/' + dsName + '/JDBCResource/' + dsName + '/JDBCDriverParams/' + dsName )
cmo.setUrl(driverUrl)
cmo.setDriverName( driverName )
cmo.setPassword(driverPassword)
cd('/JDBCSystemResources/' + dsName + '/JDBCResource/' + dsName + '/JDBCDriverParams/' + dsName+'/Properties/'+dsName)
cmo.createProperty('user')
cd('/JDBCSystemResources/' + dsName + '/JDBCResource/' + dsName + '/JDBCDriverParams/' + dsName+'/Properties/'+dsName+'/Properties/user')
cmo.setValue(driverUser)
print 'Assigning target'
cd('/SystemResources/' + dsName)
targetsArray = retrieveTargets()
set('Targets',targetsArray)
#Writing the chages to the server
save()
activate()
disconnect()
####################################
2. Create a properties file for your instance, instance.properties:
adminServer = t3://localhost:7001
adminServerUser = weblogic
adminServerPassword = password
items = 1
dsName = MyDS
jndiName = jdbc/MyDS
targets = AdminServer
driverName = oracle.jdbc.xa.client.OracleXADataSource
driverUrl = jdbc:oracle:thin:@pippo.pallino.int:1597:SERVICE
driverUser = MyUser
driverPassword = myPass
3. Run the following command:
WL_HOME\server\bin\setWLSEnv.cmd
java weblogic.WLST -loadProperties instance.properties createDS.py
There are 3 steps involved:
1. Define a jython script to create a datasource
2. Define instance specific parameters
3. Execute the script
1. Create your jython script createDS.py:
####################################
def connectAdmin() :
try:
connect(adminServerUser,adminServerPassword, adminServer)
print('Successfully connected')
except:
print 'Unable to find admin server...'
exit()
def deleteDS() :
try:
cd('/SystemResources/' + dsName)
set('Targets',jarray.array([], ObjectName))
except:
print 'Datasource not created yet'
try:
cd('/JDBCSystemResources')
datasources = cmo.getJDBCSystemResources()
for datasource in datasources :
currentDSName = datasource.getName()
if dsName == currentDSName :
try:
datasource.forceShutDown()
except:
print 'Could not shutdown datasource'
try:
cmo.destroyJDBCSystemResource(datasource)
except:
print 'Could not destroy data source'
except:
print 'could not delete datasource'
def retrieveTargets() :
targetsNames = targets.split(" ")
targetsArray = jarray.zeros(len(targetsNames),ObjectName)
index = 0
for targetName in targetsNames :
targetsArray[index] = ObjectName('com.bea:Name='+targetName+',Type=Server')
index = index + 1
return targetsArray
if __name__== "main":
print('This will enable you to create or update a Datasource')
connectAdmin()
print('Starting a edit session')
edit()
startEdit()
deleteDS()
print 'Creating data source'
# Create a new Mbean ( a JDBC resource)
cd('/')
cmo.createJDBCSystemResource(dsName)
#Naming the datasource under JDBCSystemResources
cd('/JDBCSystemResources/' + dsName + '/JDBCResource/' + dsName)
cmo.setName(dsName)
print 'Assigning JNDI name'
#Setting JNDI name
cd('/JDBCSystemResources/'+dsName+'/JDBCResource/'+dsName+'/JDBCDataSourceParams/'+dsName)
set('JNDINames',jarray.array([String(jndiName)], String))
cd('/JDBCSystemResources/' + dsName + '/JDBCResource/' + dsName + '/JDBCDriverParams/' + dsName )
cmo.setUrl(driverUrl)
cmo.setDriverName( driverName )
cmo.setPassword(driverPassword)
cd('/JDBCSystemResources/' + dsName + '/JDBCResource/' + dsName + '/JDBCDriverParams/' + dsName+'/Properties/'+dsName)
cmo.createProperty('user')
cd('/JDBCSystemResources/' + dsName + '/JDBCResource/' + dsName + '/JDBCDriverParams/' + dsName+'/Properties/'+dsName+'/Properties/user')
cmo.setValue(driverUser)
print 'Assigning target'
cd('/SystemResources/' + dsName)
targetsArray = retrieveTargets()
set('Targets',targetsArray)
#Writing the chages to the server
save()
activate()
disconnect()
####################################
2. Create a properties file for your instance, instance.properties:
adminServer = t3://localhost:7001
adminServerUser = weblogic
adminServerPassword = password
items = 1
dsName = MyDS
jndiName = jdbc/MyDS
targets = AdminServer
driverName = oracle.jdbc.xa.client.OracleXADataSource
driverUrl = jdbc:oracle:thin:@pippo.pallino.int:1597:SERVICE
driverUser = MyUser
driverPassword = myPass
3. Run the following command:
WL_HOME\server\bin\setWLSEnv.cmd
java weblogic.WLST -loadProperties instance.properties createDS.py
Wednesday, 17 February 2016
Move data between two Google App Engine applications
Use Google Cloud Storage as an intermediary mean to copy data to both GAE instances
Create a bucket in your cloud.
Open the datastore_admin of GAE
On the following screen, the data store admin will ask you for the bucket name (figure 2).
Figure 2
You can follow the status of the back. Once completed check that the tree structure of the backup
shows up in your bucket.
Very important : make sure to share publicly all files within the backup, otherwise the other application will not be able to connect and import the data. You have to go individually on every resource and check it
On data store client go the backups section where your recent backup shows up, check it,
and push on the info button. A screen showing information on your backup will show up (figure 3).
Make sure you retrieve the handle to this backup (figure 4).
The handle looks something like:
/gs/buck_name/agxzfnNpeHFvcy1ocmRyQQsSHF9BRV9EYXRhc3RvcmVBZG1pbl9PcGVyYXRpb24YgtX1FQwLEhZfQUVfQmFja3VwX0luZm9ybWF0aW9uGAEM.backup_info
Logon now to the other GAE instance datastore admin where you intend to import your data.
In the backups sectoin, in the input next to "import "back-up information" button, enter the handle retrieved previously and click on the button (figure 5).
Figure 5
The transfer of the data should take place.
Wednesday, 13 January 2016
Install embedded in-memory ActiveMQ 5.11.1 broker with XA within your Weblogic 12c JVM
Steps:
Weblogic is expecting an ra.xml configuration file describing the resource adapter instantiation parameters and the connection factories definitions. The factories definitions included therein are abstract. They do not refer to any instantiation parameters.
The only instantiation parameters are those of the resource adapter described by the sequence of config-property elements
Download here a sample of a correct resource adapter configuration file.
Our factory definition have to include the following interfaces, classes :
<outbound-resourceadapter>
<connection-definition>
<managedconnectionfactory class>
org.apache.activemq.ra.ActiveMQManagedConnectionFactory
</managedconnectionfactory-class>
<connectionfactory-interface>
javax.jms.ConnectionFactory
</connectionfactory-interface>
<connectionfactory-impl-class>
org.apache.activemq.ra.ActiveMQConnectionFactory
</connectionfactory-impl-class>
<connection-interface>
javax.jms.Connection
</connection-interface>
<connection-impl-class>
org.apache.activemq.ra.ManagedConnectionProxy
</connection-impl-class>
</connection-definition>
</outbound-resourceadapter >
The cascade of instantiation is better described by this class diagram (figure 1):
<enable-global-access-to-classes>true
<admin-objects>
<admin-object-group>
<admin-object-interface>
javax.jms.Queue
</admin-object-interface>
<!--admin-object-class>
org.apache.activemq.command.ActiveMQQueue
</admin-object-class-->
<admin-object-class>
org.apache.activemq.command.ActiveMQQueue
</admin-object-class>
<admin-object-instance>
<jndi-name>jms/queue/MyEvent</jndi->
<properties>
<property>
<name>PhysicalName</name> <value>MyEvent</value>
</property>
</properties>
</admin-object-instance>
</admin-object-group>
</admin-objects>
<outbound-resource-adapter>
<connection-definition-group>
<connection-factory-interface>javax.jms.ConnectionFactory>
<connection-instance>
<jndi-name>ConnectionFactory</jndi-name>
<connection-properties>
<pool-params>
<initial-capacity>1</initial-capacity>
<max-capacity>20</max-capacity>
<capacity-increment>1<<capacity-increment>
</pool-params>
</connection-properties>
</connection-instance>
</connection-definition-group>
</outbound-resource-adapter>
</weblogic-connector>
Download here a correct configuration of weblogic-ra.xml
Unfortunately the recovery of the connection destination carried out by the weblogic container casts for some reason the JMS destination to weblogic.jms.common.DestinationImpl. Hence, it prevents plugging in foreign broker into Weblogic.
To overcome this, it is up to you to inherit the ActiveMQDestination directly from the weblogic DestinationImpl.
I ended up with the following classes structure:
Create a jar file com.oracle.weblogic.jms _patch.jar containing the mofied class weblogic.jms.common.DestinationImpl.
In the command bat file starting the managed server where ActiveMQ is going to be hosted, add the patch to the PRE_CLASSPATH:
SET ACTIVEMQ=[activeMQ directory]
SET PRE_CLASSPATH=%PRE_CLASSPATH%;%ACTIVEMQ%\com.oracle.weblogic.jms _patch.jar;
Patch jar activemq-client-5.11.1.jar with the modified class org.apache.activemq.jndi.JNDIBaseStorable
Make sure the jar inside the rar archive are copied again into the lib directory of the domain.
Make sure both the resource adapter configuration files, ra.xml and weblogic-ra,xml lie under META-INF. Deploy the rar archive as an application to Weblogic.
To enable JMX connection please input in the JVM startup the following parameters (this will added to the environment variable JAVA_OPTIONS)
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djavax.management.builder.initial=weblogic.management.jmx.mbeanserver.WLSMBeanServerBuilder
To instruct the ActiveMQ console to which broker to connect to you need to set system properties into the JVM on which the web console in running. In our case, as we are dealing with in-memory broker, it is the same JVM of the same managed server the broker is running onto.
Hence we will add the following parameters to our JVM:
-Dwebconsole.type=properties -Dwebconsole.jms.url=vm://localhost -Dwebconsole.jmx.url=service:jmx:rmi:///jndi/rmi://localhost:9010/jmxrmi (this will added to the environment variable JAVA_OPTIONS)
Deploy the activemq-web-console-5.11.1.war to the same Managed server where the in memory broker resides.
- Patch the ActiveMQ jars
- Patch Weblogic JMS jar
- Install the resource adapter into Weblogic 12c.
- Plugin runtime system parameters to enable JMX connection from the ActiveMQ console
- Deploy the ActiveMQ Console web app
1. Patch the ActiveMQ jars
Weblogic is expecting an ra.xml configuration file describing the resource adapter instantiation parameters and the connection factories definitions. The factories definitions included therein are abstract. They do not refer to any instantiation parameters.
The only instantiation parameters are those of the resource adapter described by the sequence of config-property elements
Download here a sample of a correct resource adapter configuration file.
Our factory definition have to include the following interfaces, classes :
- managedconnectionfactory-class
- connectionfactory-interface
- connection-interface
- connection-impl-clas
The relative xml configuration looks like this:
<connection-definition>
<managedconnectionfactory class>
org.apache.activemq.ra.ActiveMQManagedConnectionFactory
</managedconnectionfactory-class>
<connectionfactory-interface>
javax.jms.ConnectionFactory
</connectionfactory-interface>
<connectionfactory-impl-class>
org.apache.activemq.ra.ActiveMQConnectionFactory
</connectionfactory-impl-class>
<connection-interface>
javax.jms.Connection
</connection-interface>
<connection-impl-class>
org.apache.activemq.ra.ManagedConnectionProxy
</connection-impl-class>
</connection-definition>
The cascade of instantiation is better described by this class diagram (figure 1):
Figure 1
However
in our case, Weblogic expects an XASession and hence we to produce and
XAConnection that will produce that XASession.. Regardless of your
setting, the ActiveMQManagedConnectionFactory by default does not instantiate such classes, hence we have to force it. We have patched this class to force it to produce an ActiveMQXAConnectionFactory. The following
diagram better described the instantiation cascade (figure 2):
Figure 2
Patch activemq-ra-5.11.1.jar with the modified class org.apache.activemq.ra.ActiveMQManagedConnectionFactory. Make sure the jar inside the rar archive are copied again into the lib directory of the Weblogic domain.
Instances created by these factories need to be specified in weblogic-ra.xml. Most important the connection factory defined therein must match a defintion found in ra.xml.
In additoin, we need to define our instance and their JNDI names under which they will they will referenced under the Weblogic JNDI tree:
<weblogic-connector xmlns="http://xmlns.oracle.com/weblogic/weblogic-connector"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-connector
http://xmlns.oracle.com/weblogic/weblogic-connector/1.0/weblogic-connector.xsd">
<jndi-name>ResourceAdapter
<enable-access-outside-app>truexmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-connector
http://xmlns.oracle.com/weblogic/weblogic-connector/1.0/weblogic-connector.xsd">
<jndi-name>ResourceAdapter
<enable-global-access-to-classes>true
<admin-objects>
<admin-object-group>
<admin-object-interface>
javax.jms.Queue
</admin-object-interface>
<!--admin-object-class>
org.apache.activemq.command.ActiveMQQueue
</admin-object-class-->
<admin-object-class>
org.apache.activemq.command.ActiveMQQueue
</admin-object-class>
<admin-object-instance>
<jndi-name>jms/queue/MyEvent</jndi->
<properties>
<property>
<name>PhysicalName</name> <value>MyEvent</value>
</property>
</properties>
</admin-object-instance>
</admin-object-group>
</admin-objects>
<outbound-resource-adapter>
<connection-definition-group>
<connection-factory-interface>javax.jms.ConnectionFactory>
<connection-instance>
<jndi-name>ConnectionFactory</jndi-name>
<connection-properties>
<pool-params>
<initial-capacity>1</initial-capacity>
<max-capacity>20</max-capacity>
<capacity-increment>1<<capacity-increment>
</pool-params>
</connection-properties>
</connection-instance>
</connection-definition-group>
</outbound-resource-adapter>
</weblogic-connector>
Download here a correct configuration of weblogic-ra.xml
2. Patch the Weblogic jar
Unfortunately the recovery of the connection destination carried out by the weblogic container casts for some reason the JMS destination to weblogic.jms.common.DestinationImpl. Hence, it prevents plugging in foreign broker into Weblogic.
To overcome this, it is up to you to inherit the ActiveMQDestination directly from the weblogic DestinationImpl.
I ended up with the following classes structure:
Figure 3
Create a jar file com.oracle.weblogic.jms _patch.jar containing the mofied class weblogic.jms.common.DestinationImpl.
In the command bat file starting the managed server where ActiveMQ is going to be hosted, add the patch to the PRE_CLASSPATH:
SET ACTIVEMQ=[activeMQ directory]
SET PRE_CLASSPATH=%PRE_CLASSPATH%;%ACTIVEMQ%\com.oracle.weblogic.jms _patch.jar;
Patch jar activemq-client-5.11.1.jar with the modified class org.apache.activemq.jndi.JNDIBaseStorable
Make sure the jar inside the rar archive are copied again into the lib directory of the domain.
3. Install the resource adapter into Weblogic 12c.
Make sure both the resource adapter configuration files, ra.xml and weblogic-ra,xml lie under META-INF. Deploy the rar archive as an application to Weblogic.
4. Plugin runtime system parameters to enable JMX connection from the ActiveMQ console
To enable JMX connection please input in the JVM startup the following parameters (this will added to the environment variable JAVA_OPTIONS)
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djavax.management.builder.initial=weblogic.management.jmx.mbeanserver.WLSMBeanServerBuilder
To instruct the ActiveMQ console to which broker to connect to you need to set system properties into the JVM on which the web console in running. In our case, as we are dealing with in-memory broker, it is the same JVM of the same managed server the broker is running onto.
Hence we will add the following parameters to our JVM:
-Dwebconsole.type=properties -Dwebconsole.jms.url=vm://localhost -Dwebconsole.jmx.url=service:jmx:rmi:///jndi/rmi://localhost:9010/jmxrmi (this will added to the environment variable JAVA_OPTIONS)
5. Deploy the ActiveMQ Console webapp
Deploy the activemq-web-console-5.11.1.war to the same Managed server where the in memory broker resides.
Friday, 8 January 2016
Wildfly/JBoss slf4j bindig clash with the a webapp slf4j binding
I recently stumbled on a ClassCastException on using the following piece code in a web app deployed on JBoss:
LoggerContext logCtx = (LoggerContext) LoggerFactory.getILoggerFactory();
After some digging I managed to figure out the reason.
JBoss root classloader already uses slf4j for its own puropses and probably binds its own implementation. When the web app classloader kicks in, it's already too late, the slf4j is already bound.
A solution would be to intervene at the web app running and load JBoss's slf4j library. I have done that by adding JBoss specific deployment descriptor to the WEB-INF directory, namely, the file jboss-deployment-structure.xml:
<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<deployment>
<exclusions>
<module name="org.slf4j"/>
</exclusions>
</deployment>
<jboss-deployment-structure>
LoggerContext logCtx = (LoggerContext) LoggerFactory.getILoggerFactory();
After some digging I managed to figure out the reason.
JBoss root classloader already uses slf4j for its own puropses and probably binds its own implementation. When the web app classloader kicks in, it's already too late, the slf4j is already bound.
A solution would be to intervene at the web app running and load JBoss's slf4j library. I have done that by adding JBoss specific deployment descriptor to the WEB-INF directory, namely, the file jboss-deployment-structure.xml:
<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<deployment>
<exclusions>
<module name="org.slf4j"/>
</exclusions>
</deployment>
<jboss-deployment-structure>
Subscribe to:
Comments (Atom)
Blog Archive
-
►
2018
(9)
- ► 08/05 - 08/12 (2)
- ► 07/01 - 07/08 (2)
- ► 06/17 - 06/24 (2)
- ► 05/20 - 05/27 (2)
- ► 05/13 - 05/20 (1)
-
▼
2016
(6)
- ► 02/14 - 02/21 (2)
-
►
2015
(2)
- ► 12/20 - 12/27 (1)
- ► 12/06 - 12/13 (1)
-
►
2010
(2)
- ► 09/26 - 10/03 (1)
- ► 03/07 - 03/14 (1)
-
►
2009
(2)
- ► 11/08 - 11/15 (1)
- ► 09/20 - 09/27 (1)








