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
Search This Blog
Tuesday, 30 December 2008
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
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.
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
You can see in the run() method we don't call close on the statement itself which leads to a code leak.
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.
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
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
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
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
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:
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
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
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)
{
}
}
}
}
Monday, 25 August 2008
How to do a "desc emp" from JDBC
If you ever try to do a "desc emp" from a JDBC program , that won't work as that's a SQL*Plus command only, but here is how to write an SQL statement to do that which can easily be converted into a JDBC program and used.
Firstly here is what we get when we describe the EMP table in SQL*Plus.
Now here is the SQL we can use to get the same output from an SQL query.
The output of that is as follows from the query above , identical to a "desc emp", or close enough, couple more decodes will sort out a few minors issues , but seems to work for most tables I tested it against.
So with a bind variable defined it would simply be as follows
And then easily be integrated into a JDBC program, I did this over the web using a JSP page, which lists all user tables and adds a DESCRIBE button next to the table name to get the output above when clicked.
Firstly here is what we get when we describe the EMP table in SQL*Plus.
SCOTT@linux10g> desc emp;
Name Null? Type
----------------------------------- -------- ------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
Now here is the SQL we can use to get the same output from an SQL query.
select
column_name as "Name",
decode(NULLABLE, 'Y', '', 'N', 'Not Null') as "Null",
data_type||decode(data_type,
'NUMBER', decode(DATA_PRECISION, NULL, '',
'('||DATA_PRECISION||','||data_scale||')'),
'VARCHAR2', '('||data_length||')',
'CHAR', '('||data_length||')') as "Type"
from user_tab_columns
where table_name = 'EMP'
The output of that is as follows from the query above , identical to a "desc emp", or close enough, couple more decodes will sort out a few minors issues , but seems to work for most tables I tested it against.
Name Null Type
------------------------------ -------- ------------------------------
EMPNO Not Null NUMBER(4,0)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4,0)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2,0)
So with a bind variable defined it would simply be as follows
select
column_name as "Name",
decode(NULLABLE, 'Y', '', 'N', 'Not Null') as "Null",
data_type||decode(data_type,
'NUMBER', decode(DATA_PRECISION, NULL, '',
'('||DATA_PRECISION||','||data_scale||')'),
'VARCHAR2', '('||data_length||')',
'CHAR', '('||data_length||')') as "Type"
from user_tab_columns
where table_name = ?
And then easily be integrated into a JDBC program, I did this over the web using a JSP page, which lists all user tables and adds a DESCRIBE button next to the table name to get the output above when clicked.
Monday, 11 August 2008
Determining if any active HTTP Sessions exist for deployed applications in OAS 10.1.3.x
Recently I was asked how to determine if any current HTTP sessions exist for an application. The reason for needing this information was so that the application could be redeployed only when no HTTP sessions existed and the application was currently not being used. It turns out there is an MBean which can give you that information.
The Mbean is as follows:
His how to access it from the MBean browser in ASC and get the information on HTTP sessions for your deployed applications.
1. Log into ASC
2. Click on the container you wish to use.
3. Click on the link "Administration".
4. Click on the "Go To Task" icon as follows.
JMX -> System MBean Browser
5. Expand the ClassLoading node in the navigation pane, then select the singleton MBean instance.
6. Click the Operations tab in the right-hand pane, then click the executeQuery operation.
Three versions of the executeQuery operation are exposed. Click the version that takes one parameter.
7. For the value parameter enter in the following and press the "Invoke Operation" button
HttpSessions(details)
You will end up with output as follows which will give you the amount of HTTP sessions which currently exist for each deployed application.
** Summary at Aug 11, 2008 9:57:43 AM **
Total Sessions: 0
Total Attributes: 0
Total Session Size: 0 bytes
Largest Session: N/A
Youngest Session: N/A
Idlest Session: N/A
Oldest Session: N/A
** Details **
[ADFBC-HA:adfhaprofile]
No active sessions
[SimpleWS:WebServices]
No active sessions
[WebServiceDemo-SimpleWS-WS:WebServices]
No active sessions
...
The Mbean is as follows:
oc4j:j2eeType=ClassLoading,name=singleton,J2EEServer=standalone |
His how to access it from the MBean browser in ASC and get the information on HTTP sessions for your deployed applications.
1. Log into ASC
2. Click on the container you wish to use.
3. Click on the link "Administration".
4. Click on the "Go To Task" icon as follows.
JMX -> System MBean Browser
5. Expand the ClassLoading node in the navigation pane, then select the singleton MBean instance.
6. Click the Operations tab in the right-hand pane, then click the executeQuery operation.
Three versions of the executeQuery operation are exposed. Click the version that takes one parameter.
7. For the value parameter enter in the following and press the "Invoke Operation" button
HttpSessions(details)
You will end up with output as follows which will give you the amount of HTTP sessions which currently exist for each deployed application.
** Summary at Aug 11, 2008 9:57:43 AM **
Total Sessions: 0
Total Attributes: 0
Total Session Size: 0 bytes
Largest Session: N/A
Youngest Session: N/A
Idlest Session: N/A
Oldest Session: N/A
** Details **
[ADFBC-HA:adfhaprofile]
No active sessions
[SimpleWS:WebServices]
No active sessions
[WebServiceDemo-SimpleWS-WS:WebServices]
No active sessions
...
Wednesday, 30 July 2008
Enable Remote Clients To Access OAS 10.1.3.x Server-Side JNDI Context From Deployed Applications
In order for remote clients to access a OAS 10.1.3.x JNDI Server-Side context they must authenticate with the server prior to doing a look up. Here is how to enable such access from a remote J2SE client and what setup steps are required to achieve this for deployed applications, thus avoiding using privileged users such as oc4jadmin.
This example is based on JAZN-XML security provider at the instance level.
1. Log into Application Server Console (ASC).
2. Click on your container you wish to use.
3. Click on administration link.
4. Click on the icon for the security task with a description as follows -> "Configure security providers, create/delete/view users and roles".
Here we will just use "Instance" level security which will enable this user we create to be used by all applications within this instance.
5. Click on the button "Instance Level Security".
6. Click on the link "Realms".
7. You will see a column called "Users" which will have an amount of users, simple click on the amount to go to the next screen.
8. Click on the "Create" button.
9. Enter the following.
10. Press OK.
So the user we want to use will be "test" with a password as "test123", with this in place we now must grant access to the JNDI context to the correct group so that remote users which are part of this group can access the JNDI resource. This is done as shown below within a deployment descriptor for each deployed application which contains JNDI objects such as a Data Source or an EJB. The file is placed within a META-INF directory of an EAR file.
orion-application.xml
As you can see the namespace-access has been setup to allow users which are part of the role "users" access to the JNDI Server-Side context for the deployed application.
So with a deployment descriptor added to my application named "pastest" and deployed, I can then perform a JNDI look up of resources within that application as the user "test" as shown below.
For more information see the documentation below.
Oracle® Containers for J2EE Security Guide
10g (10.1.3.1.0)
Part Number B28957-01
http://download.oracle.com/docs/cd/B31017_01/web.1013/b28957/loginmod.htm#BABIICGC
This example is based on JAZN-XML security provider at the instance level.
1. Log into Application Server Console (ASC).
2. Click on your container you wish to use.
3. Click on administration link.
4. Click on the icon for the security task with a description as follows -> "Configure security providers, create/delete/view users and roles".
Here we will just use "Instance" level security which will enable this user we create to be used by all applications within this instance.
5. Click on the button "Instance Level Security".
6. Click on the link "Realms".
7. You will see a column called "Users" which will have an amount of users, simple click on the amount to go to the next screen.
8. Click on the "Create" button.
9. Enter the following.
Name - test
Password - test123
Confirm Password - test123
Shuttle Across "users" to the "Selected Roles" Area
Note: You can create your own role but you must make sure you set the check box "Grant RMI Login Permission". We are using the "users" role as that has been done already for us.10. Press OK.
So the user we want to use will be "test" with a password as "test123", with this in place we now must grant access to the JNDI context to the correct group so that remote users which are part of this group can access the JNDI resource. This is done as shown below within a deployment descriptor for each deployed application which contains JNDI objects such as a Data Source or an EJB. The file is placed within a META-INF directory of an EAR file.
orion-application.xml
<?xml version = '1.0' encoding = 'windows-1252'?>
<orion-application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://xmlns.oracle.com/oracleas/schema/orion-application-10_0.xsd">
<namespace-access>
<read-access>
<namespace-resource root="">
<security-role-mapping>
<group name="users" />
</security-role-mapping>
</namespace-resource>
</read-access>
<write-access>
<namespace-resource root="">
<security-role-mapping>
<group name="users" />
</security-role-mapping>
</namespace-resource>
</write-access>
</namespace-access>
</orion-application>
As you can see the namespace-access has been setup to allow users which are part of the role "users" access to the JNDI Server-Side context for the deployed application.
So with a deployment descriptor added to my application named "pastest" and deployed, I can then perform a JNDI look up of resources within that application as the user "test" as shown below.
private Context getInitialContext() throws NamingException
{
Hashtable env = new Hashtable();
// Standalone OC4J connection details
env.put( Context.INITIAL_CONTEXT_FACTORY,
"oracle.j2ee.rmi.RMIInitialContextFactory" );
env.put( Context.SECURITY_PRINCIPAL, "test" );
env.put( Context.SECURITY_CREDENTIALS, "test123" );
env.put(Context.PROVIDER_URL, "ormi://localhost:23791/pastest");
return new InitialContext( env );
}
For more information see the documentation below.
Oracle® Containers for J2EE Security Guide
10g (10.1.3.1.0)
Part Number B28957-01
http://download.oracle.com/docs/cd/B31017_01/web.1013/b28957/loginmod.htm#BABIICGC
Subscribe to:
Posts (Atom)