Friday, 18 March 2016

JAX-RS 2.0 on Weblogic 12.1.3

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.


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 :

       

<?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

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

Select an entity to backup  and push the button "Backup entities" (figure 1)

Figure 1


On the following screen, the data store admin will ask you for the bucket name (figure 2).

Confirm by pressing on "Backup entities"


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).



Figure 3

Make sure you retrieve the handle to this backup (figure 4).


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:

  1. Patch the ActiveMQ jars
  2. Patch Weblogic JMS jar
  3. Install the resource adapter into Weblogic 12c.
  4. Plugin runtime system parameters to enable JMX connection from the ActiveMQ console
  5. 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:
       
          
     <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-access-outside-app>true
    <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>

About Me

My Photo