Search This Blog

Monday, 25 May 2009

ADF11g fail over within a Weblogic 10.3 Cluster

I recently setup failover for a simple ADF11g application within a Oracle weblogic 10.3 cluster. Once you have your Oracle Weblogic 10.3 cluster in place you really only need to do 2 things on your application side.

Part A

1. Right click on your application module and select "Configurations".
2. Select your config and press the "Edit" button.
3. Click on "Pooling and Scalability" tab.
4. Select the check box "Failover Transaction State Upon Managed Release".
5. Press OK

This will generate the following for your bc4j.xcfg file in your model project with fail over feature switched on.
<AppModuleConfig DeployPlatform="LOCAL"
JDBCName="scott"
jbo.project="model.Model"
name="AppModuleLocal"
ApplicationName="model.AppModule">
<AM-Pooling jbo.dofailover="true"/>
<Security AppModuleJndiName="model.AppModule"/>
</AppModuleConfig>

This provides the most pessimistic protection against application server failure. The application module instances' state is always saved and may be activated by any application module instance at any time. Of course, this capability comes at expense of the additional overhead of eager passivation on each request.

For more information on state management see the following link:
http://download.oracle.com/docs/cd/E12839_01/web.1111/b31974/bcstatemgmt.htm#BABHIBDG

Part B

Now finally we need to ensure our view project which is packaged as a WAR file includes a weblogic.xml file within the WEB-INF folder as follows. This will ensure we setup our application to use HTTP Session replication in the event of a node failure.

<?xml version = '1.0' encoding = 'windows-1252'?>
<weblogic-web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app.xsd"
xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app">
<session-descriptor>
<timeout-secs>300</timeout-secs>
<invalidation-interval-secs>60</invalidation-interval-secs>
<persistent-store-type>replicated_if_clustered</persistent-store-type>
</session-descriptor>
</weblogic-web-app>

While testing this I used the following managed server property to determine which
managed server I was accessing at the time.

String instance = System.getProperty("weblogic.Name");

Wednesday, 6 May 2009

Oracle Weblogic 10.3 Using SSL with the Oracle JDBC THIN driver

I recently created this how to with product management showing how to configure a data source in Oracle WebLogic 10.3 using SSL with the JDBC THIN driver.

http://www.oracle.com/technology/products/weblogic/howto/jdbcssl/index.html

Thursday, 30 April 2009

ADF 11g - Groovy expression for default value of todays date

I have an EO with one Date column which I wanted to default to today's date on record creation. Normally I would create a EO class and add the "create" method to the class to achieve this but I found it's even easier to use a groovy expression which I did as follows.

1. Double click on EO to bring it up in the code editor "Overview" tab.
2. Click on attributes
3. Select the "Date" attribute and press the edit icon
4. Place the following into the "Value" field

String.format('%tF', new Date())

Note: This will ensure we retrieve today's date and format the date into the format which our Date EO attribute is using which in this case is "YYYY-MM-DD".

5. Select the check box "Expression" for the "Value Type"

Note: You can also use the built in Groovy expressions adf.currentDate and adf.currentDateTime that you can use.

6. Press OK.

Now when we create a new record the default value for the date will be todays date using a groovy expression.

You can see from this groovy script that unless we format the output ADF will throw a runtime error with just the use of new Date() without any formatting.

Groovy Script:

def today= new Date() //represents the date and time when it is created
println today

println String.format('%tF', today)

Output:

Thu Apr 30 11:51:54 EST 2009
2009-04-30

More information on groovy and ADF can be found here.

http://www.oracle.com/technology/products/jdev/11/how-tos/groovy/introduction_to_groovy.pdf

Friday, 24 April 2009

Configuring JDeveloper 11g to use Struts 2

I was recently asked how to setup JDeveloper 11g web projects to use Struts 2 here is what I did to get this working. Keep in mind JDeveloper has design time support for Struts 1.x but not Struts 2 so this is a manual process.

1. Start Jdeveloper 11g
2. Select File | New | General | Applications | Generic Application
3. Name the application "Struts2Demo" and click next
4. Name the project "Demo" and press finish

Now at this point we want to add a simple JSP page to the project so
we end up with a web project , we will need to configure this to use
struts2 manually which we will do soon.

5. Right click on the project and select "New | Web Tier | JSP"
6. call the JSP "sayhello.jsp" and append "\pages" to the end of
the directory path so it creates the JSP in a sub directory called
"pages".

At this point you will need to download the Struts libraries. At a minimum,
you will need to put the following in your WEB-INF/lib directory of your
JDeveloper project:

* struts2-core.jar (The framework itself)
* xwork.jar (Struts 2 is built on the XWork 2 framework)
* ognl.jar (Object Graph Notation Language is used throughout the framework)
* freemarker.jar (Freemarker is used to create UI tag templates in Struts 2)
* commons-logging.jar (Used to log to log4j or JDK logging)

Download struts2 from here. I am using 2.1.6 here.

http://struts.apache.org/download.cgi

7. Refresh the navigator to ensure your project shows the WEB-INF\lib folder
and the required struts2 libraries.
8. Double click on the project to invoke project properties dialog and
select "Libraries\Classpath"
9. Add the 5 jars files to the project and press OK. You could create
a single library and add the 5 JAR files to that library if you like.

Now we are ready to configure our project to use struts2.

10. Open up the web.xml and add the following entries

<?xml version = '1.0' encoding = 'windows-1252'?>
<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"
version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee">
<description>Empty web.xml file for Web Application</description>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>35</session-timeout>
</session-config>
<mime-mapping>
<extension>html</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>txt</extension>
<mime-type>text/plain</mime-type>
</mime-mapping>
</web-app>

11. Create a java class as follows

package demo.struts2.action;

import com.opensymphony.xwork2.ActionSupport;

public class ExampleAction extends ActionSupport
{
private String message;

public String execute() throws Exception
{
this.message = "Hello from Struts 2";
return SUCCESS;
}

public void setMessage(String message)
{
this.message = message;
}

public String getMessage()
{
return message;
}
}

12. Struts places its configuration in a struts.xml file. Create the file
at the root of your source folder for the project as follow. We’ll need
to add our new action to the struts.xml file.

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
<!-- Configuration for the default package. -->
<package name="default" extends="struts-default">
<action name="ExampleAction" class="demo.struts2.action.ExampleAction">
<result name="success">/pages/sayhello.jsp</result>
</action>
</package>
</struts>

13. Finally ensure the "sayhello.jsp" looks as follows

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ page contentType="text/html;charset=windows-1252"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<title>sayhello</title>
</head>
<body>
<h2><s:property value="message" /></h2>
</body>
</html>


Now we need to add the Struts2 tag library to our project.

14. Double click on the project to invoke the project properties and
select "JSP Tag Libraries"
15. Click the "Add" button
16. Select "Project" and then press the "New" button
17. Navigate to "public_html\WEB-INF\lib\struts2-core.jar" and
press 'Open"
18. Verify it finds "Struts tage 2.2.3".
19. Press OK
20. Again double click on the project to invoke the project properties
and select "Java EE Application" and set the context root to "struts2demo"
and press Ok
21. Select File | save All
22. Select Build | Demo.jpr to ensure it compiles fine.
23. Navigate to the default domain directory LIB folder of the integrated server
and add the 5 JAR files we need for struts 2

eg: D:\jdev11g-boxer\jdeveloper\jdev\system11.1.1.0.31.52.05\DefaultDomain\lib

commons-logging-1.0.4.jar
freemarker-2.3.13.jar
ognl-2.6.11.jar
struts2-core-2.1.6.jar
xwork-2.1.2.jar

Now JDeveloper doesn't provide support for running struts2 applications so you
will need to create some sort of index.jsp page which will redirect to our action
we created. Here we will just run the JSP and then alter the URL to invoke
your action so that the view page will render correctly.

23. Right click on "sayhello.jsp" and select "Run" to start the Integrated
WLS.

You will notice it displays nothing , that is due to the fact we have not
run the actual action which we do by altering the URL as follows

http://127.0.0.1:7101/struts2demo/ExampleAction.action

Note: I am not 100% sure why I need to add the struts2 JAR files to
the defualt domain LIB folder of my WLS server as I would expect it to find
those files in the WEB-INF\lib directory of the application which is how
struts1 works and I believe how struts2 should work. I even went back
to JDeveloper 10.1.3 and found that indeed it works there without
having to manilpulate it's classpath which proves the files in WEB-INF\lib
of the application is all that is needed.

Not sure why WLS doesn't work that way?

Friday, 17 April 2009

How to Add Row Filtering to an af:table which wasn't setup initially for this

When you add an ADF Read Only table to a JSF page you can add "Row Filtering" to the table. Here is how to set this on a table which was not setup with "Row Filtering" and you now wish to enable it now.

1. Right click on the JSF page which contains the "af:table" and select "Go To Page Definition".
2. In the structure window right click on "Executables" and select "Insert inside executables -> search region".
3. Enter an ID as follows -> SrListQuery
4. Alter binding XML file so it adds these 3 attributes as shown.

<searchRegion
Binds="SrlistView1Iterator"
Criteria=""
Customizer="oracle.jbo.uicli.binding.JUSearchBindingCustomizer"
id="SrListQuery"/>

5. Switch back to the JSF page and go to the source editor and add these 3 attributes in bold to your "af:table". You must use "SrListQuery" which is the Id for the search region executable.

<af:table
value="#{bindings.SrlistView1.collectionModel}"
var="row" rows="#{bindings.SrlistView1.rangeSize}"
emptyText="#{bindings.SrlistView1.viewable ? 'No rows yet.' : 'Access Denied.'}"
fetchSize="#{bindings.SrlistView1.rangeSize}"
filterModel="#{bindings.SrListQuery.queryDescriptor}"
queryListener="#{bindings.SrListQuery.processQuery}"
selectedRowKeys="#{bindings.SrlistView1.collectionModel.selectedRow}"
selectionListener="#{bindings.SrlistView1.collectionModel.makeCurrent}"
rowSelection="single" id="table"
filterVisible="true">

Finally we need to determine which columns we wish to allow filtering to occur for which we do as follows

6. Select the "af:column" tag in the structure window.
7. Click on the + symbol to expand the "Behavior" options in the property inspector.
8. Set "Filterable" to "true".
9. Repeat steps 6 - 8 for each column you wish to be filterable.

Now when you switch to design view of your JSF page you should see your table which has a row on the top of the table which enables row filtering for the columns you enabled this for.

Wednesday, 8 April 2009

New Wait option for Sequential Redeployment in a clustered OAS 10.1.3.2 setup

When you have an application using HTTP session replication setup in a HA cluster on OAS 10.1.3.2 and above you can easily ensure that when you deploy a new version of that application it will continue to run with no down time. What's important here is you select the correct deployment option.

Redeploying with ASC

If you use ASC for the deployment then your effectively redeploying to the cluster in parallel - all nodes in cluster will get notified and process the deployment in parallel. That means you will most likey have down time and get errors for those currently using your application.

Redeploy with admin_client.jar or redeploy Ant task

With these two deployment choices you can specify sequential and keepsettings options however in some circumstances the session state of an application may be lost when you redeploy an application to a cluster.

In Oracle Containers for J2EE release 10.1.3.2 or 10.1.3.1, you can use either the waitsec parameter of the admin_client.jar -sequential waitsec subswitch or the sequentialDelay property of the redeploy Ant task to specify a number of seconds between redeployments to different OC4J instances in a cluster. This delay can provide enough time for replication of session state

For example, the following admin_client.jar command specifies a wait time of 15 seconds between redeployments to different OC4J instances:
java -jar admin_client.jar deployer:cluster:opmn://host:port/home oc4jadmin
password -redeploy -file "myapp.ear" -deploymentName rolling -sequential 15
-keepsettings
It's documented here, make sure your using 10.1.3.2 or above for this

http://download.oracle.com/docs/cd/B32110_01/relnotes.1013/b32200/oc4j.htm#CHDJJFIG
10.1.14 New Wait Option for Sequential Redeployment to a Cluster

Thursday, 2 April 2009

CYGWIN Script to copy ADF 11g JARS required for Tomcat

A work colleague told me he had to setup ADF 11g on tomcat 6.x and was lead to this link on what JAR files was required to be copied over to the %CATALINA_HOME%/lib folder.

http://blogs.oracle.com/dana/2009/01/how_to_deploy_a_11g_adf_applic_1.html

Here is a small script I wrote which will copy all those JAR files into a TEMP directory to save you time trying to find them one by one. This is a CYGWIN script as I don't know how to write BAT files.

1. Go into your JDeveloper 11g root directory as follows

papicell@papicell-au ~/d/jdev11g-boxer

2. Create a script as follows called "doCopyADF.sh"

#!/bin/sh
COPY_DIR=/cygdrive/d/temp/adf11g
export COPY_DIR;

cat adfjars.txt | while read filename
do
echo "Copying file $filename"
echo ""
find . -name "$filename" -exec cp {} $COPY_DIR \;
done


echo "All files copied.."

3. Now before you run it we need to create a list of ADF 11g JAR files it needs to find in a file called "adfjars.txt".

I simple used VI to create the list of files we need which we retrieved from the blog entry above.

adf-controller-api.jar
adf-controller-rt-common.jar
adf-controller.jar
adf-faces-databinding-rt.jar
adf-pageflow-dtrt.jar
adf-pageflow-fwk.jar
adf-pageflow-impl.jar
adf-pageflow-rc.jar
adf-richclient-api-11.jar
adf-richclient-impl-11.jar
adf-share-base.jar
adf-share-ca.jar
adf-share-support.jar
adflibfilter.jar
adflogginghandler.jar
adfm.jar
adfmweb.jar
cache.jar
commons-el.jar
db-ca.jar
dms.jar
dvt-faces.jar
dvt-jclient.jar
dvt-utils.jar
fmw_audit.jar
identitystore.jar
inspect4.jar
javatools-nodeps.jar
javax.management.j2ee_1.0.jar
jewt4.jar
jmxframework.jar
jmxspi.jar
jps-api.jar
jps-common.jar
jps-ee.jar
jps-internal.jar
jps-unsupported-api.jar
jsf-api.jar
jsf-ri.jar
jstl.jar
mdsrt.jar
ojdbc6.jar
oracle-el.jar
oraclepki.jar
org.apache.commons.beanutils_1.6.jar
org.apache.commons.collections_3.1.jar
org.apache.commons.logging_1.0.4.jar
osdt_cert.jar
osdt_core.jar
share.jar
standard.jar
trinidad-api.jar
trinidad-impl.jar
wls-api.jar
xercesImpl.jar
xmlef.jar
xmlparserv2.jar

4. Finally we need to edit the script to ensure we select a directory which exists to copy the JAR files into.

COPY_DIR=/cygdrive/d/temp/adf11g
export COPY_DIR;

5. Run as follows, ensuring you made it executable using "chmod +x doCopyADF.sh".

./doCopyADF.sh

Note: The list of required JAR files may not be 100% correct but with this script you can simple add/remove files from "adfjars.txt" to ensure you get the correct JAR files you need.

Example output.

papicell@papicell-au ~/d/jdev11g-boxer
$ ./doCopyADF.sh
Copying file adf-controller-api.jar

Copying file adf-controller-rt-common.jar

Copying file adf-controller.jar

Copying file adf-faces-databinding-rt.jar

Copying file adf-pageflow-dtrt.jar

Copying file adf-pageflow-fwk.jar

Copying file adf-pageflow-impl.jar

Copying file adf-pageflow-rc.jar

Copying file adf-richclient-api-11.jar

Copying file adf-richclient-impl-11.jar

Copying file adf-share-base.jar

Copying file adf-share-ca.jar

Copying file adf-share-support.jar

.....

Wednesday, 25 March 2009

Providing logout functionailty for Secure OC4J Apps in 10.1.3.x

I recently had to determine how to logout of an OC4J 10.1.3.x application which was secured against a 3rd party LDAP server, using HTTP Basic authentication. Normally for web based applications you can control when to logout calling invalidate() from the HTTPSession object as shown below or wait until the session times out which it will then do for you automatically.

HttpSession.invalidate()


The problem here is when using HTTP basic authentication browsers typically 'cache' HTTP basic authentication credentials and re-send them when necessary.

Specifying FORM as the authentication scheme in web.xml (along with HttpSession.invalidate()) will address this issue of provinding a logout link which gives you control of when your user wants to logout. The authentication scheme chosen is depending on your requirements so if logout isn't important then HTTP basic will do, but typically I would expect HTTP basic to be used very rarely.

Tuesday, 17 March 2009

Getting debug output from utl_dbws PLSQL package

When calling web services from an oracle database you can use utl_dbws package. There are times though that you need to debug it to determine why it may be failing. This can be achieved as follows.

call dbms_java.set_output(100000);

Example output from a SQL file as follows. This example is calling a JAXRPC 1.4 web service from OAS 10.1.3.4

SQL:

set serveroutput on

call dbms_java.set_output(100000);

-- call web service methods here now for end point below
-- http://beast.au.oracle.com:7777/wsrocks/DemoWSSoapHttpPort
-- WSDL = http://beast.au.oracle.com:7777/wsrocks/DemoWSSoapHttpPort?WSDL

prompt
prompt Calling method todaysDate from web service
prompt

select PasWS102.todaysDate from dual;

prompt
prompt Calling method echoString from web service
prompt

select PasWS102.echoString('Pas') from dual;

Output:


SQL*Plus: Release 10.2.0.1.0 - Production on Tue Mar 17 08:56:38 2009

Copyright (c) 1982, 2005, Oracle. All rights reserved.

Enter password: *****

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

Call completed.

Calling method todaysDate from web service


TODAYSDATE
----------------------------------------------------------------------------------------------------
Tue Mar 17 07:57:37 EST 2009

ServiceFacotory: oracle.j2ee.ws.client.ServiceFactoryImpl@bb101899
WSDL: null
Service: oracle.j2ee.ws.client.BasicService@ce6cb3d5
*** Created service: -677524827 - oracle.jpub.runtime.dbws.DbwsProxy$ServiceProxy@2968f5e4 ***
ServiceProxy.get(-677524827) = oracle.jpub.runtime.dbws.DbwsProxy$ServiceProxy@2968f5e4
** Calling web service method {todaysDate} **
setProperty(javax.xml.rpc.soap.http.soapaction.use, true)
setProperty(javax.xml.rpc.soap.http.soapaction.uri, http://pas.au.ws//todaysDate)
setProperty(javax.xml.rpc.soap.operation.style, document)
** Invoking web service method {todaysDate} **
Attribute 0: http://pas.au.ws/types/: xmlns, http://pas.au.ws/types/
createElement(todaysDateElement,null,http://pas.au.ws/types/)
Attribute 0: http://pas.au.ws/types/: xmlns, http://pas.au.ws/types/
request:

response:

Tue Mar 17 07:57:37 EST 2009

** Successfully invoked web service method {todaysDate} **

Calling method echoString from web service


PASWS102.ECHOSTRING('PAS')
----------------------------------------------------------------------------------------------------
Pas

ServiceFacotory: oracle.j2ee.ws.client.ServiceFactoryImpl@bb101899
WSDL: null
Service: oracle.j2ee.ws.client.BasicService@d05260ad
*** Created service: -677524826 - oracle.jpub.runtime.dbws.DbwsProxy$ServiceProxy@7789dbfd ***
ServiceProxy.get(-677524826) = oracle.jpub.runtime.dbws.DbwsProxy$ServiceProxy@7789dbfd
** Calling web service method {echoString} **
setProperty(javax.xml.rpc.soap.http.soapaction.use, true)
setProperty(javax.xml.rpc.soap.http.soapaction.uri, http://pas.au.ws//echoString)
setProperty(javax.xml.rpc.soap.operation.style, document)
** Invoking web service method {echoString} **
Attribute 0: http://pas.au.ws/types/: xmlns, http://pas.au.ws/types/
createElement(echoStringElement,null,http://pas.au.ws/types/)
Attribute 0: http://pas.au.ws/types/: xmlns, http://pas.au.ws/types/
dbwsproxy.element.node.child.0: 1, null
createElement(s,null,http://pas.au.ws/types/)
dbwsproxy.text.node.child.0: 3, Pas
request:

Pas

response:

Pas

** Successfully invoked web service method {echoString} **
SCOTT@linux10g>

Tuesday, 3 March 2009

OAS 10.1.3.x : SSL With Oracle JDBC Thin Driver

The following how-to demonstrates, creating a self signed oracle wallet for the server and client, configuring the database to use TCPS and finally create a data source on OC4J 10.1.3.x.

Create the wallets

For an example on how to create the server and client keys/certificates see the following metalink note. The examples are created using orapki utility which creates a standard PKCS12 format to store X.509 certificates and private keys.

Note 762286.1 - End To End Examples of using SSL With Oracle's JDBC THIN Driver

Setup OC4J to use JDBC/THIN with SSL

1. Create a java class as follows, and package it up in a JAR file called "JDBCStartup.jar". This startup class file enables Oracle PKI provider dynamically.

/**
*
* add the following lines to your server.xml
<init-library path="<path_to_JDBCSSLSetup.jar>" />
<startup-classes>
<startup-class classname="JDBCSSLSetup" failure-is-fatal="false">
<execution-order>0</execution-order>
</startup-class>
</startup-classes>

*/


import javax.naming.*;
import java.util.*;
import java.security.Security;
import oracle.security.pki.OraclePKIProvider;
import oracle.j2ee.server.OC4JStartup;

/**
* JDBC over SSL setup startup class for OC4J
*/


public class JDBCSSLSetup implements OC4JStartup
{
/**
* Public, no-argument constructor: required by the Oracle startup class spec
*/

public JDBCSSLSetup()
{
}

public String preDeploy(Hashtable args, Context context) throws Exception
{
// instantiate OraclePKIProvider and put it into provider slot #3
Security.insertProviderAt(new OraclePKIProvider(), 3);
System.out.println("JDBCSSLSetup startup class: OraclePKIProvider has been successfully instantiated");

return "ok";
}

public String postDeploy(Hashtable args, Context context) throws Exception
{
return null;
}
}

2. Place the JAR file into $ORACLE_HOME/j2ee/{container-name}/applib directory.

3. Edit $ORACLE_HOME/j2ee/{container-name}/config/server.xml as follows to add the startup class to the container.


<init-library path="../applib/JDBCStartup.jar" />
<startup-classes>
<startup-class classname="JDBCSSLSetup" failure-is-fatal="true" >
<execution-order>0</execution-order>
</startup-class>
</startup-classes>


4. Restart the container as shown below.

> opmnctl stopproc process-type=pas

> opmnctl startproc process-type=pas

5. OAS 10..1.3.x comes with JDBC driver 10.1.0.5 , you will need to use the latest 10g JDBC driver or 11g JDBC driver, to switch to that driver follow the following metalink how to document. You should add the required JAR files below to the shared library along with the JDBC JAR file.

Note 420303.1 - How to Use The Latest Thin JDBC Driver Across All Applications For a 10.1.3.x OAS Container

If you are using 11g database you will also need these 2 JAR files added to the shared library.
  • $ORACLE_HOME/jlib/osdt_cert.jar
  • $ORACLE_HOME/jlib/osdt_core.jar
If you are using 10g database you will also need this JAR file added to the shared library.
  • $ORACLE_HOME/jlib/ojpse.jar
6. You should be using the latest JDBC driver as per your $ORACLE_HOME/j2ee/{container-name}/config/system-application.xml. In this example we are using the 11.1.0.7 JDBC driver.


<import-shared-library name="oracle.jdbc" min-version="11.1.0.7"/>


7. Now re-start the container to ensure it picks up the latest JDBC driver which should have been done in the note above.

> opmnctl stopproc process-type=pas

> opmnctl startproc process-type=pas


8. Now you can go ahead and create a data source which is using TCPS either through asconsole or manually editing $ORACLE_HOME/j2ee/{container-name}/config/data-sources.xml

Here we will manually edit data-sources.xml and add a managed data source and connection pool to support our SSL setup. We must use the factory class "oracle.jdbc.OracleDriver" as we need to pass properties to the driver.

<managed-data-source
connection-pool-name="TCPSConnectionPool"
jndi-name="jdbc/jdbcSSLDS"
name="jdbc/jdbcSSLDS"/>

<connection-pool name="TCPSConnectionPool">
<connection-factory
factory-class="oracle.jdbc.OracleDriver"
user="scott"
password="tiger"
url="jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)
(HOST=beast.au.oracle.com)(PORT=2484))(CONNECT_DATA=(SERVICE_NAME=linux11g)))"

commit-record-table-name="">
<property
name="javax.net.ssl.trustStore"
value
="/home/u01/app/oracle/product/1013AS_red/network/admin/wallets/client/ewallet.p12"/>
<property
name
="javax.net.ssl.trustStoreType"
value
="PKCS12"/>
<property
name
="javax.net.ssl.trustStorePassword"
value
="myclient123"/>
</connection-factory>
</connection-pool>

In the example above we connect to the database through TCPS for SSL with Encryption and Authentication.

Note: The connect string should include TCPS as shown above.

9. Now in this example we manually edited data-sources.xml so we must re-start the container once again to pick up those changes.

> opmnctl stopproc process-type=pas

> opmnctl startproc process-type=pas


10. Finally we can test our data source using asconsole Data Sources page as shown below.




More Information

For more information regarding SSL With Oracle JDBC Thin Driver see the following white paper

http://www.oracle.com/technology/tech/java/sqlj_jdbc/pdf/wp-oracle-jdbc_thin_ssl.pdf

Monday, 2 March 2009

Java Stored Procedure remotely connecting to another database

I very rarely use JavaSP but I had a request to connect to a remote database from a JavaSP. My first thought was to use a database link but the request required a direct connection to the remote database using JDBC/THIN driver. here is how I got it working.

1. Create a class as follows which contains one method to connect to a remote database.


import java.sql.Connection;

import java.sql.SQLException;

import oracle.jdbc.pool.OracleDataSource;

public class RemoteDBTest
{
public static String remoteConnection()
throws SQLException
{
StringBuffer sb = new StringBuffer();
String userId = "scott";
String password = "tiger";
String url =
"jdbc:oracle:thin:@acampanaro-pc2.au.oracle.com:1521:linux102";
Connection conn = null;

OracleDataSource ods = new OracleDataSource();
ods.setUser(userId);
ods.setPassword(password);
ods.setURL(url);
conn = ods.getConnection();

sb.append("Auto commit = " + conn.getAutoCommit());
conn.close();

return sb.toString();
}
}


2. Load the class into the database and create a call specification, I used JDeveloper 10.1.3.4 as this makes light work of the task as shown by the output below. The class was loaded as user SCOTT.

Invoking loadjava on connection 'scott-linux102' with arguments:
-order -resolve -thin
Loadjava finished.
Executing SQL Statement:
CREATE OR REPLACE FUNCTION remoteConnection RETURN VARCHAR2 AUTHID CURRENT_USER AS LANGUAGE JAVA NAME 'RemoteDBTest.remoteConnection() return java.lang.String';
Success.
Publishing finished.

3. Now I need to grant some privileges to enable me to remotely connect from my database to another database using JAVA. There 2 are as follows, which must be executed as SYS.

SYS@LINUX10G> exec dbms_java.grant_permission( 'SCOTT', 'SYS:java.net.SocketPermission', 'acampanaro-pc2.au.oracle.com', 'resolve');

PL/SQL procedure successfully completed.

SYS@LINUX10G> exec dbms_java.grant_permission( 'SCOTT', 'SYS:java.net.SocketPermission', '10.187.80.13:1521', 'connect,resolve');

PL/SQL procedure successfully completed.

4. Now we can call our JavaSP and verify if we have successfully connected.

SCOTT@LINUX10G> select remoteconnection from dual;

REMOTECONNECTION
------------------------------------------------------------

Auto commit = true

What you will find is if you don't execute the required privileges then you will be told when you try to run the JavaSP that you don't have required permissions to do this. His an example of what error you may receive. Lucky for me oracle gives me the command I need to run which made this easy to setup.

SCOTT@LINUX10G> select remoteconnection from dual;
select remoteconnection from dual
*
ERROR at line 1:
ORA-29532: Java call terminated by uncaught Java exception: java.security.AccessControlException: the Permission
(java.net.SocketPermission 10.187.80.13:1521 connect,resolve) has not been granted to SCOTT. The PL/SQL to grant this
is dbms_java.grant_permission( 'SCOTT', 'SYS:java.net.SocketPermission', '10.187.80.13:1521', 'connect,resolve' )

Tuesday, 24 February 2009

How to Create a JDBC/OCI Connection Pool For Stand Alone OC4J 10.1.3.x

Recently I had to setup JDBC/OCI connection pool in stand alone OC4J 10.1.3.x using an oracle client 10.2.0.3. The problem here is OC4J 10.1.3.x comes with JDBC driver 10.1.0.5 of ojdbc14.jar. Which means you will have issues using the 10.2.0.3 oracle client libraries.

As a result of that you must upgrade the driver to use the client version JDBC driver as well as set various environment variables before starting stand alone OC4J. The steps are as follows.

Note: This is based on OC4J 10.1.3.4 and on a windows environment, using instant client 10.2.0.3

1. Download 10.2.0.3 instant client as follows, in my case installed in directory as follows

D:\jdev\instant-clients\10203

You can download the 10.2.0.3 version from here.

http://www.oracle.com/technology/software/tech/oci/instantclient/

2. Open up command window and set environment variables as follows

set PATH=D:\jdev\instant-clients\10203;%PATH%
set TNS_ADMIN=D:\jdev\instant-clients\10203

Note: A tnsnames.ora exists in the directory D:\jdev\instant-clients\10203 and has the following entry which I will use in stand alone OC4J shortly.

LINUX10G =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = xxxx.au.oracle.com)(PORT = 1522))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = linux10g)
)
)

3. Start stand alone OC4J as follows, ensuring you use the same commend window from step 2 above.

set ORACLE_HOME=D:\jdev\stand-alone-oc4j\10134
set JAVA_HOME=D:\jdev\jdevprod\10134\jdk

D:\jdev\stand-alone-oc4j\10134\bin>oc4j -start
Starting OC4J from D:\jdev\stand-alone-oc4j\10134\j2ee\home ...
09/02/23 13:42:29 Oracle Containers for J2EE 10g (10.1.3.4.0) initialized

4. OC4J 10.1.3.x is using 10.1.0.5 JDBC driver which means it will have issues connecting using 10.2.0.3 instant client so we have to upgrade the JDBC driver to 10.2.0.3 as shown below for the whole container. Follow this metalink note to fix that so it matches the same version of instant client which would mean you use ojdbc14.jar from 10.2.0.3 jar file of ojdbc14.jar.

Note 420303.1 - How to Use The Latest Thin JDBC Driver Across All Applications For a 10.1.3.x OAS Container

You can download the 10.2.0.3 JDBC driver jar file from this link, but it should be available in your oracle client install.

http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html

5. Stop stand alone OC4J to pick up the shared library change.
6. Start stand alone OC4J.
7. Create a data source as follows.


<connection-pool name="ocitest-pool">
<connection-factory factory-class="oracle.jdbc.pool.OracleDataSource"
user="scott" password="tiger" url="jdbc:oracle:oci:@LINUX10G"/>
</connection-pool>


For more information on data sources refer to the following documentation.

Oracle® Containers for J2EE Services Guide
10g (10.1.3.1.0)
Part Number B28958-01
http://download-uk.oracle.com/docs/cd/B31017_01/web.1013/b28958/datasrc.htm#BABIDCBJ

Thursday, 19 February 2009

OC4J 10.1.3.x start order of Resource Adapters

In order to control the start order of Resource Adapters for an application you can use the start-order tag as described here in the docs within your oc4j-connectors.xml

Oracle® Containers for J2EE Resource Adapter Administrator's Guide
10g (10.1.3.1.0)
Part Number B28956-01
http://download.oracle.com/docs/cd/B32110_01/web.1013/b28956/xmlcnfg.htm#sthref532

Thursday, 12 February 2009

Determine the Security Providers for the JVM

Note for myself: While working with Oracle's JDBC/THIN driver with SSL this comes in handy

package pas.test;

import java.security.Provider;
import java.security.Security;

public class GetProviders
{
public GetProviders()
{
}

public static void main(String[] args)
{
Provider[] pl = Security.getProviders();
System.out.println("Printing Available Security.getProviders()");
for (int i=0; i < pl.length; i++)
{
System.out.println("\n" + i + ". " + pl[i].toString());
System.out.println("Name: " + pl[i].getName());
System.out.println("Version: " + pl[i].getVersion());
System.out.println("Info: " + pl[i].getInfo());
}
}
}

Output:

Printing Available Security.getProviders()

0. SUN version 1.5
Name: SUN
Version: 1.5
Info: SUN (DSA key/parameter generation; DSA signing; SHA-1, MD5 digests; SecureRandom; X.509 certificates; JKS keystore; PKIX CertPathValidator; PKIX CertPathBuilder; LDAP, Collection CertStores)

1. SunRsaSign version 1.5
Name: SunRsaSign
Version: 1.5
Info: Sun RSA signature provider

2. SunJSSE version 1.5
Name: SunJSSE
Version: 1.5
Info: Sun JSSE provider(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)

3. SunJCE version 1.5
Name: SunJCE
Version: 1.5
Info: SunJCE Provider (implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC)

4. SunJGSS version 1.0
Name: SunJGSS
Version: 1.0
Info: Sun (Kerberos v5)

5. SunSASL version 1.5
Name: SunSASL
Version: 1.5
Info: Sun SASL provider(implements client mechanisms for: DIGEST-MD5, GSSAPI, EXTERNAL, PLAIN, CRAM-MD5; server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5)

Thursday, 5 February 2009

Oracle Weblogic 10.3 / RAC 11g Integration How To

I worked with product management to create a how to for Oracle Weblogic 10.3 / RAC 11g Integration. The URL is on OTN now as follows. It comes with a sample web application to test your configuration out as well.

http://www.oracle.com/technology/products/weblogic/howto/rac/index.html

It comes with a white paper as well created by a product manager

http://www.oracle.com/technology/products/weblogic/OracleWLS_RAC.pdf