Search This Blog

Tuesday, 20 January 2009

JDBC THIN / SSL 11g Runtime Issue - java.security.InvalidAlgorithmParameterException

I have been working on setting up JDBC THIN /SSL 11g (ojdbc6.jar) with JDK 1.6 against an 11g database. Previously I only ever done this with 10g, so here is a common runtime issue I run into while setting this up from the client side.

Runtime excepotion as follows:

java.sql.SQLRecoverableException: Io exception: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParame
terException: the trustAnchors parameter must be non-empty

Due to the fact I was using (PKCS12) wallets (ewallet.p12) I needed place Oracle PKI provider in java.security for my JDK 1.6 runtime environment as shown below.

File : D:\jdev\jdk16\jre\lib\security\java.security

security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=oracle.security.pki.OraclePKIProvider
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=sun.security.mscapi.SunMSCAPI

Once that was done the error dissapeared I was able to run my client side JDBC THIN/ SSL demo.

D:\temp\pas-ssl>java -classpath ./classes;.;D:\temp\pas-ssl\lib\ojdbc6.jar;D:\temp\pas-ssl\lib\oraclepki.jar support.au.jdbc.ssl.J
DBCSSLWalletTrustore
Start: Tue Jan 20 09:16:20 EST 2009
Conncted as DATABASE USER SCOTT
Ended: Tue Jan 20 09:16:21 EST 2009

D:\temp\pas-ssl>

So the code for this was as follows :


/*
* Author: Pas Apicella
*/

package support.au.jdbc.ssl;

import java.security.Security;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import java.util.Date;
import java.util.Properties;

import oracle.jdbc.pool.OracleDataSource;


public class JDBCSSLWalletTrustore
{
private static OracleDataSource ods = null;
private static final String TRUSTSTORE =
"D:/jdev11g-boxer/jdeveloper/jdev/mywork/JDBCSSL11g/wallets/client/ewallet.p12";
private static final String TRUSTSTORETYPE = "PKCS12";
private static final String TRUSTSTOREPASSWORD = "myclient123";
private static final String DBURL =
"jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)" +
"(HOST=beast.au.oracle.com)(PORT=2484))" +
"(CONNECT_DATA=(SERVICE_NAME=linux11g)))";

private static final String DBUSER = "scott";
private static final String DBPASSWD = "tiger";

public JDBCSSLWalletTrustore()
{
Security.addProvider(new oracle.security.pki.OraclePKIProvider());
}

public void run () throws SQLException
{
String sql = "select user from dual";
Statement stmt = null;
ResultSet rset = null;
Connection conn = null;

try
{
conn = getConnection();
stmt = conn.createStatement();
rset = stmt.executeQuery(sql);
rset.next();

if (rset != null)
{
System.out.println
(String.format("Conncted as DATABASE USER %s",
rset.getString(1)));
}
}
finally
{
if (stmt != null)
{
stmt.close();
}

if (rset != null)
{
rset.close();
}

if (conn != null)
{
conn.close();
}
}
}

public static Connection getConnection() throws SQLException
{
Properties props = new Properties();

props.setProperty("javax.net.ssl.trustStore",
TRUSTSTORE);
props.setProperty("javax.net.ssl.trustStoreType", TRUSTSTORETYPE);
props.setProperty("javax.net.ssl.trustStorePassword", TRUSTSTOREPASSWORD);

ods = new OracleDataSource();
ods.setUser(DBUSER);
ods.setPassword(DBPASSWD);
ods.setURL(DBURL);
ods.setConnectionProperties(props);

Connection conn = ods.getConnection();

return conn;
}

public static void main(String[] args)
{
System.out.println("Start: " + new Date());
JDBCSSLWalletTrustore testssl = new JDBCSSLWalletTrustore();

try
{
testssl.run();
}
catch (SQLException se)
{
System.out.println("SQL Exception occurred: ");
se.printStackTrace();
}
catch (Exception e)
{
System.out.println("Exception occurred: ");
e.printStackTrace();
}

System.out.println("Ended: " + new Date());
}


}

If you have trouble getting a JDBC THIN / SSL demo to work , it's worth tuning on this java option at run time to get more detailed information, here is what we get when we turn it on with the same code above, the output is far more detailed to enable you to debug why it may not be working for you.

-Djavax.net.debug=ssl

Output
-------

Start: Tue Jan 20 11:10:05 EST 2009
adding as trusted cert:
Subject: OU=Class 3 Public Primary Certification Authority, O="VeriSign, Inc.", C=US
Issuer: OU=Class 3 Public Primary Certification Authority, O="VeriSign, Inc.", C=US
Algorithm: RSA; Serial number: 0x70bae41d10d92934b638ca7b03ccbabf
Valid from Mon Jan 29 11:00:00 EST 1996 until Wed Aug 02 09:59:59 EST 2028

adding as trusted cert:
Subject: CN=Entrust.net Certification Authority (2048), OU=(c) 1999 Entrust.net Limited, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), O=Entrust.net
Issuer: CN=Entrust.net Certification Authority (2048), OU=(c) 1999 Entrust.net Limited, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), O=Entrust.net
Algorithm: RSA; Serial number: 0x3863b966
Valid from Sat Dec 25 04:50:51 EST 1999 until Wed Dec 25 05:20:51 EST 2019

.....

.....

*** Finished
verify_data: { 196, 181, 216, 111, 12, 62, 126, 237, 120, 137, 1, 126 }
***
main, WRITE: TLSv1 Handshake, length = 48
main, READ: TLSv1 Change Cipher Spec, length = 1
main, READ: TLSv1 Handshake, length = 48
*** Finished
verify_data: { 50, 203, 187, 227, 95, 124, 39, 44, 151, 160, 209, 59 }
***
%% Didn't cache non-resumable client session: [Session-2, TLS_RSA_WITH_AES_128_CBC_SHA]
main, WRITE: TLSv1 Application Data, length = 224
main, READ: TLSv1 Application Data, length = 48
main, WRITE: TLSv1 Application Data, length = 192
main, READ: TLSv1 Application Data, length = 160
main, WRITE: TLSv1 Application Data, length = 64
main, READ: TLSv1 Application Data, length = 208
main, WRITE: TLSv1 Application Data, length = 2080
main, WRITE: TLSv1 Application Data, length = 176
main, READ: TLSv1 Application Data, length = 2032
main, READ: TLSv1 Application Data, length = 288
main, WRITE: TLSv1 Application Data, length = 192
main, READ: TLSv1 Application Data, length = 224
main, WRITE: TLSv1 Application Data, length = 1056
main, READ: TLSv1 Application Data, length = 1360
main, WRITE: TLSv1 Application Data, length = 48
main, READ: TLSv1 Application Data, length = 208
main, WRITE: TLSv1 Application Data, length = 112
main, READ: TLSv1 Application Data, length = 512
Conncted as DATABASE USER SCOTT
main, WRITE: TLSv1 Application Data, length = 48
main, READ: TLSv1 Application Data, length = 48
main, WRITE: TLSv1 Application Data, length = 32
main, called close()
main, called closeInternal(true)
main, SEND TLSv1 ALERT: warning, description = close_notify
main, WRITE: TLSv1 Alert, length = 32
Ended: Tue Jan 20 11:10:07 EST 2009

Tuesday, 30 December 2008

Creating a READ ONLY user for Application Server Control 10.1.3.x

Today I was asked how to create a user with a read-only user for access to the Application Server Control pages. I always use oc4jadmin and obviously that built in account has full rights, but it turns out the easiest way to create a new user with READ ONLY access is as follows

1. Log into ASC
2. Click on the link "Setup" at the top of the page.
3. Click on "Users"
4. Click on the "Create" button.
5. Enter new username/password and press OK

By default the user you create here will be one with read-only access which by default will be assigned the role "
ascontrol_monitor".

Now you can login with this new user with
read-only user access to the Application Server Control pages.

The administration roles are documented here.

http://otndnld.oracle.co.jp/document/products/as10g/101300/B25221_03/core.1013/b25209/tools.htm
Table 2-2 Administrative Roles That You Can Assign to Application Server Control Administrators

Monday, 15 December 2008

Associate an IDE DB Connection to a Workspace for Web projects in JDeveloper 11g

In JDeveloper 10g you could easily deploy all database connections when running a web project in the embedded OC4J server thus allowing each connection to be represented as a data source at runtime. Turns out the same can be done in JDeveloper 11g and Weblogic Integrated server however the steps are a little different.

1. View -> Database Navigator
2. Drag the IDE connection you wish to use in your workspace. The end result is as follows for the Workspace "WebLogicStuff"





3. Now whenever you run any web project from WebLogicStuff workspace then the database connection "scott" will automatically be deployed as an application level data source.

4. In order to access the connection "scott" we should use a JNDI location as follows within our code.

java:comp/env/jdbc/scottDS

The format would be as follows, depending on the connection name.

java:comp/env/jdbc/{jdevide-connection-name}DS

Here is some java code we can then use to perform a JNDI lookup of the data source via a simple method which requires the location above to be passed to the method.

private Connection getConnection (String dataSourceLocation)
throws NamingException, SQLException
{
Connection conn = null;

// Get a context for the JNDI look up
Context ctx = new InitialContext();

// Look up a data source
javax.sql.DataSource ds
= (javax.sql.DataSource) ctx.lookup (dataSourceLocation);

// Create a connection object
conn = ds.getConnection();

return conn;
}

Thursday, 13 November 2008

Simple Example of Memory Profiling in JDeveloper 11g

In the 11g JDBC Developer's guide below it clearly specifies the following.

http://download.oracle.com/docs/cd/B28359_01/java.111/b31224/oraint.htm#i1058743

Important: The cursor associated with a REF CURSOR is closed whenever the statement object that produced the REF CURSOR is closed. Unlike in past releases, the cursor associated with a REF CURSOR is not closed when the result set object in which the REF CURSOR was materialized is closed.

So here is how I used JDeveloper memory profiler to verify that this indeed was the case.

1. new java class as follows


package pas.jdbc.refcursor;
import java.sql.*;

import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleDriver;
import oracle.jdbc.OracleTypes;

public class RefCursorExample
{
private boolean detailsDisplayed = false;
private Connection conn = null;

public RefCursorExample() throws SQLException
{
conn = getConnection();
}

public void run () throws SQLException
{
CallableStatement cstmt = null;
ResultSet cursor = null;

try
{
if (!detailsDisplayed)
{
displayDeatils(conn);
detailsDisplayed = true;
}

// Use a PL/SQL block to open the cursor
cstmt = conn.prepareCall
("begin open ? for select ename from emp; end;");

cstmt.registerOutParameter(1, OracleTypes.CURSOR);
cstmt.execute();
cursor = ((OracleCallableStatement)cstmt).getCursor(1);

// Use the cursor like a standard ResultSet
while (cursor.next ())
{
System.out.println (cursor.getString(1));
}
System.out.println("\n");
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally
{
if (cursor != null)
{
cursor.close();
}
}


}

public void displayDeatils (Connection conn) throws SQLException
{
// Create Oracle DatabaseMetaData object
DatabaseMetaData meta = conn.getMetaData ();

// gets driver info:

System.out.println("\n=============\nDatabase Product Name is ... " +
meta.getDatabaseProductName());
System.out.println("\nDatabase Product Version is " +
meta.getDatabaseProductVersion());
System.out.println("\n=============\nJDBC Driver Name is ........ " +
meta.getDriverName());
System.out.println("\nJDBC Driver Version is ..... " +
meta.getDriverVersion());
System.out.println("\nJDBC Driver Major Version is " +
meta.getDriverMajorVersion());
System.out.println("\nJDBC Driver Minor Version is " +
meta.getDriverMinorVersion());
System.out.println("\n=============");
}

public static Connection getConnection() throws SQLException
{
String username = "scott";
String password = "tiger";
String thinConn = "jdbc:oracle:thin:@beast.au.oracle.com:1521:linux11g";
DriverManager.registerDriver(new OracleDriver());
Connection conn =
DriverManager.getConnection(thinConn, username, password);
conn.setAutoCommit(false);
return conn;
}

public static void main(String[] args) throws Exception
{
RefCursorExample refCursorExample = new RefCursorExample();
refCursorExample.run();

for (int i = 1; i <= 5; i++)
{
System.out.println("Run #" + i + "\n");
refCursorExample.run();
}

Thread.sleep(30000);

System.out.println("finished");
}
}



You can see in the run() method we don't call close on the statement itself which leads to a code leak.


finally
{
if (cursor != null)
{
cursor.close();
}
}


2. In the project edit the default profile by double clicking on the project and selecting "Run/Deug/Profile" and then select "Edit" for default profile, then select "Tools Settings/Profiler" and select the checkbox "Begin Use Case on application Startup"

3. Press Ok twice

Now we are ready to memory profile the application. As ou can see from the code we call the method run() 5 times so lets see if we can see the Statement leak.

4. Select Run -> Memory profile

A snapshot is taken as soon as the program runs, and then it sleeps for 30 seconds before finally completing. Click on the icon "End task" and set the class filter to "T4CStatement"






5. You will see 2 columns , one called "New" the other one called "Final Num"

Both are 6 which shows that we have 6 "T4CStatement" classes still in the heap.

Now lets fix the code to actually call close() on the statement in the finally block of the run() mnethod as the 11g JDBC Developer's guide suggests to.

if (cstmt != null)
{
cstmt.close();
}

6. Now profile the class "RefCursorExample" again and you will see that we no longer have a build up of "T4CStatement" as previously examined, when the statement was closed as well.

We have "New" as 6 and "Final Num" as 1 as expected.

Monday, 13 October 2008

JDeveloper 11g deploying a web project to WLS 10.3 using JSTL 1.2 tag library fails

When you create a web project using JSP and add the JSTL 1.2 core library to the project and eventually go to deploy your project as a WAR to an external WLS 10.3 server you may end up with the following exception and it fails to deploy.

weblogic.management.DeploymentException: [J2EE:160149]Error while processing library references. Unresolved Webapp Library references for "weblogic.servlet.internal.WebAppServletContext@17409f8 - appName: 'jstl12demo', name: 'jstl12demo.war', context-path: '/jstl12demo', spec-version: '2.5'", defined in weblogic.xml [Extension-Name: jstl, Specification-Version: 1.2, exact-match: false].

What's odd is the integrated server works fine no issue there. The reason for this is the integrated server has the JSTL 1.2 library already defined. So the way to get around this in an external WLS 10.3 server is to do it one of 2 ways.

Option 1 - Deploy JSTL 1.2 libraries with the archive itself

1. Edit your deployment profile.
2. Select File Groups - WEB-INF/Lib - Contributors
3. Check the following to include the JSTL 1.2 libraries
  • JSTL 1.2
  • JSTL 1.2 Tags
4. Press OK
5. Redeploy and this time you get a successfull deployment.

---- Deployment started. ---- 13/10/2008 13:47:12
Target platform is (Weblogic 10.3).
Running dependency analysis...
Building...
2008-10-13 13:47:16.921: Writing WAR file to D:\jdev11gbea\jdeveloper\jdev\mywork\JSTL12\Project1\deploy\jstl12demo.war
2008-10-13 13:47:16.937: Wrote WAR file to D:\jdev11gbea\jdeveloper\jdev\mywork\JSTL12\Project1\deploy\jstl12demo.war
Deploying Application...
Application Deployed Successfully.
Elapsed time for deployment: 7 seconds
---- Deployment finished. ---- 13/10/2008 13:47:19


Option 2 - Setup WLS 10.3 to include a library for the JSTL 1.2 tags

1. Log into WLS 10.3 administration console
2. Click on deployments
3. Press the install button
4. Navigate to the following directory and select "jstl-1.2.war"

/u01/bea103/wlserver_10.3/common/deployable-libraries

5. Click next
6. Select the radio option to install this as a library
7. Select the target server for this library
8. Click next
9. Click finish

Now attempt to deploy your project which includes JSTL 1.2 tag references and it should deploy fine.

---- Deployment started. ---- 13/10/2008 13:55:03
Target platform is (Weblogic 10.3).
Running dependency analysis...
Building...
2008-10-13 13:55:07.625: Writing WAR file to D:\jdev11gbea\jdeveloper\jdev\mywork\JSTL12\Project1\deploy\jstl12demo.war
2008-10-13 13:55:07.64: Wrote WAR file to D:\jdev11gbea\jdeveloper\jdev\mywork\JSTL12\Project1\deploy\jstl12demo.war
Deploying Application...
Application Deployed Successfully.
Elapsed time for deployment: 7 seconds
---- Deployment finished. ---- 13/10/2008 13:55:10

By default due to using the JSTL 1.2 tag library when your deploying to WLS 10.3 the WAR file includes a file called weblogic.xml with contents as follows. As you can see the library reference we created is automatically used as per your project requirements to use JSTL 1.2. Once this is done all deployments targeted to the server using the JSTL 1.2 library you created will work as long as they use this in there deployment descriptor.

weblogic.xml


<?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">
<library-ref>
<library-name>jstl</library-name>
<specification-version>1.2</specification-version>
</library-ref>
</weblogic-web-app>


Wednesday, 8 October 2008

JDeveloper 11g JAX-WS proxy cannot read WSDL

JDeveloper 11g (BOXER) was released today, and if your using web services it's worth reading the release notes as follows.

http://www.oracle.com/technology/products/jdev/htdocs/11/knownissues.html#wsd

When creating a JAX-WS proxy for a external web service you may get an error as follows

Exception in thread "main" javax.xml.ws.WebServiceException: weblogic.wsee.wsdl.WsdlException: Failed to read wsdl file from url due to -- java.io.FileNotFoundException: D:\jdev11gbea\jdeveloper\jdev\mywork\WebServiceProxy\Project1\classes\SimpleWS.wsdl (The system cannot find the file specified)
at weblogic.wsee.jaxws.spi.WLSProvider.readWSDL(WLSProvider.java:306)

The easiest way to avoid this is on page 3 of 8 of the JAX-WS Proxy wizard uncheck "Copy WSDL into project"

The issue is release noted as follows.

http://www.oracle.com/technology/products/jdev/htdocs/11/knownissues.html#wsd12

Thursday, 4 September 2008

Displaying OC4J JVM MBean Statistics from a JMX Client

The JVM Mbean within an OC4J 10.1.3.x container has some useful statistic which are displayed in ASC MBean browser. Here is some code which shows how to obtain those from a JMX client.

So the MBean we want to access is as follows:

oc4j:j2eeType=JVM,name=single,J2EEServer=standalone

And the statistics we want to display which ASC shows for us are as follows:
  • FreeHeapSize
  • ActiveThreads
  • HeapSize
So here is the code we will use from a JMX Client. The method which obtains the statistics we need is called "showStats(ObjectName)"


package oracle.support.oc4j.standalone;

import java.text.DateFormat;

import java.util.Date;
import java.util.logging.Logger;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.j2ee.statistics.JVMStats;
import javax.management.j2ee.statistics.Statistic;
import javax.management.j2ee.statistics.BoundedRangeStatistic;

public class JVMMonitor implements Runnable
{
private final Logger logger = Logger.getLogger(this.getClass().getName());
private static final DateFormat DATEFORMAT = DateFormat.getInstance();
private OC4JConnection con = null;
private MBeanServerConnection mbs = null;
private String targetMBean = "oc4j:j2eeType=JVM,name=single,J2EEServer=standalone";
private ObjectName mbean = null;

public JVMMonitor() throws Exception
{
// retrieve an OC4JConnection object this is a singleton class
con = OC4JConnection.getInstance();
mbs = con.getConnection();
mbean = new ObjectName(targetMBean);
System.out.println("** JVM Details **");
System.out.printf("Opmn Managed: %s\n",
mbs.getAttribute(mbean, "opmnEnabled"));
System.out.printf("Java Version: %s\n",
mbs.getAttribute(mbean, "javaVersion"));
System.out.printf("Java Vendor: %s\n",
mbs.getAttribute(mbean, "javaVendor"));
System.out.printf("Host Node: %s\n",
mbs.getAttribute(mbean, "node"));
System.out.printf("RMI Port: %s\n",
mbs.getAttribute(mbean, "rmiPort"));
System.out.printf("RMIS Port: %s\n",
mbs.getAttribute(mbean, "rmisPort"));
System.out.printf("RMI IP: %s\n",
mbs.getAttribute(mbean, "rmiServerAddress"));

}

public void run ()
{

System.out.println("\n");
try
{
System.out.printf("--> Current JVM Details [%s]\n\n",
DATEFORMAT.format(new Date()));


showStats(mbean);
System.out.printf("\n<-- End...\n");
}
catch (Exception e)
{
System.out.println("Error in run()");
e.printStackTrace();
}
finally
{
//con.close();
}
}

private void showStats(ObjectName cp) throws Exception
{

JVMStats stats =
(JVMStats) mbs.getAttribute(cp, "stats");

Object mem = null;
mem = mbs.getAttribute(cp, "totalMemory");
Long memLong = null;
memLong = (Long) mem;

System.out.printf("Total Memory: %s\n", memLong.intValue()/1024/1024 + "M");

mem = mbs.getAttribute(cp, "freeMemory");
memLong = (Long) mem;
System.out.printf("Free Memory: %s\n",
memLong.intValue()/1024/1024 + "M");

System.out.printf("HeapSize: %s\n",
stats.getHeapSize().getCurrent()/1024 + "M");
System.out.printf("HighWaterMark: %s\n",
stats.getHeapSize().getHighWaterMark()/1024 + "M");
System.out.printf("LowWaterMark: %s\n",
stats.getHeapSize().getLowWaterMark()/1024 + "M");

Statistic[] allStats = stats.getStatistics();

for (Statistic s: allStats)
{
if (!s.getName().equalsIgnoreCase("UpTime"))
{
System.out.println("\n--");
System.out.printf("JVM Statistic [%s]\n", s.getName());
System.out.printf("Description : %s\n", s.getDescription());
System.out.printf("Unit : %s\n", s.getUnit());
System.out.printf("Last Sample Time : %s\n", new Date(s.getLastSampleTime()));

BoundedRangeStatistic brs = (BoundedRangeStatistic) s;

if (s.getUnit().equals("THREADS"))
{
System.out.printf("High WaterMark : %s\n", brs.getHighWaterMark());
System.out.printf("Low WaterMark : %s\n", brs.getLowWaterMark());
System.out.printf("Current : %s\n", brs.getCurrent());
}
else
{
System.out.printf("High WaterMark : %s\n", brs.getHighWaterMark()/1024 + "M");
System.out.printf("Low WaterMark : %s\n", brs.getLowWaterMark()/1024 + "M");
System.out.printf("Current : %s\n", brs.getCurrent()/1024 + "M");
}

}
}


}

}



So the output would then be as follows:

** JVM Details **
Opmn Managed: true
Java Version: 1.5.0_06
Java Vendor: Sun Microsystems Inc.
Host Node: beast.au.oracle.com
RMI Port: 12406
RMIS Port: 12706
RMI IP: 10.187.80.70

JVMMonitor
Period to report results in seconds is : 5

** Started [4/09/08 11:29] with 5(sec) interval between reports **


--> Current JVM Details [4/09/08 11:29]

Total Memory: 515M
Free Memory: 453M
HeapSize: 515M
HighWaterMark: 550M
LowWaterMark: 504M

--
JVM Statistic [FreeHeapSize]
Description : The amount of free heap memory
Unit : KILO BYTES
Last Sample Time : Thu Sep 04 11:06:44 EST 2008
High WaterMark : 515M
Low WaterMark : 433M
Current : 453M

--
JVM Statistic [ActiveThreads]
Description : The number of active thread(s)
Unit : THREADS
Last Sample Time : Thu Sep 04 11:06:44 EST 2008
High WaterMark : 64
Low WaterMark : 4
Current : 64

--
JVM Statistic [HeapSize]
Description : The size of the JVM's heap
Unit : KILO BYTES
Last Sample Time : Thu Sep 04 11:06:44 EST 2008
High WaterMark : 550M
Low WaterMark : 504M
Current : 515M

<-- End...

Few people asked for this class itself.

OC4JConnection.java


  
package oracle.support.oc4j.standalone;

import java.io.FileInputStream;

import java.util.Hashtable;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import oracle.oc4j.admin.jmx.remote.api.JMXConnectorConstant;

public class OC4JConnection
{
private static Properties myProperties = new Properties();
private JMXConnector jmxCon = null;
private static OC4JConnection instance = null;
private final Logger logger = Logger.getLogger(this.getClass().getName());
private String username = null;
private String password = null;
private String url = null;

private OC4JConnection
(Properties inProps) throws Exception
{

try
{
processProps(inProps);

logger.log
(Level.INFO, "Username = " + username);
logger.log
(Level.INFO, "Service URL = " + url);

// Define the connection target
JMXServiceURL serviceUrl = new JMXServiceURL(url);

Hashtable env = new Hashtable();

env.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
"oracle.oc4j.admin.jmx.remote");

Hashtable credentials = new Hashtable();

credentials.put
(JMXConnectorConstant.CREDENTIALS_LOGIN_KEY, username);
credentials.put(JMXConnectorConstant.CREDENTIALS_PASSWORD_KEY,
password);

env.put(JMXConnector.CREDENTIALS, credentials);

jmxCon = JMXConnectorFactory.newJMXConnector(serviceUrl, env);
// Connect to the target OC4J instance defined in the JMXServiceURL
jmxCon.connect();
logger.log
(Level.INFO, "Connected to OC4J");
}
catch (Exception e)
{
logger.log
(Level.SEVERE,
"** [OC4JConnection()] : Unable to obtain Stand Alone Connection",
e);
e.printStackTrace();
}
}

public static OC4JConnection getInstance() throws Exception
{
if(instance == null)
{
myProperties.load(new FileInputStream("build.properties"));
instance = new OC4JConnection(myProperties);
}

return instance;
}

private void processProps(Properties inProps)
{
username = inProps.getProperty("username");
password = inProps.getProperty("password");
url = inProps.getProperty("serviceurl");

}

public MBeanServerConnection getConnection ()
{
MBeanServerConnection mbs = null;

if (jmxCon != null)
{
try
{
mbs = jmxCon.getMBeanServerConnection();
}
catch (Throwable t)
{
logger.log
(Level.SEVERE,
"**[getConnection] : Unable to retrieve MBeanServerConnection");
}
}

return mbs;
}

/**
* Determine if the client is currently connected
* @return true if connected
*/
public boolean isConnected ()
{
boolean ret = false;
if (jmxCon == null)
{
return false;
}
else
{
try
{
jmxCon.getConnectionId();
return true;
}
catch (Throwable t)
{
//
}
}

return ret;
}

/**
* Close the JMXConnector.
*/
public void close ()
{
if (jmxCon != null)
{
try
{
jmxCon.close();
jmxCon = null;
logger.log
(Level.INFO, "Closed Connection to OC4J");
}
catch (Throwable t)
{
}
}
}
}