Long been a user of Eclipse, but haven't spent much time with the various enterprise plugins. So I'm now downloading the all-in-one Oracle Enterprise Pack for Eclipse 11g for Windows from OTN.
And nicely, it seems to comes in at only a 186MB download.
23 April 2009
18 February 2009
WebLogic Server Domain Builder
Have had to spend some time with the Domain Builder / Config Wizard combination this week. It seems like they provide a pretty useful capacity to build out a domain, which you can then run the domain builder over to produce a template, which you can use as a cookie cutter to reproduce it when needed. I confess I've barely gone beyond snorkel depth with it, but it looks like it could be pretty handy to reproduce setups, deploy sets of applications, etc.
Anyone got any feedback on its use in the real world?
Anyone got any feedback on its use in the real world?
06 February 2009
Using Derby Network Server with OC4J
Seeing as how I spent sometime this morning on getting OC4J DataSources to work with Derby, and there wasn't much information out there in googleland on it, I thought I'd post some information.
The request, paraphrased was: "I need to use the ClientXADataSource with OC4J to connect to a remote Derby server, but it only seems to connect to localhost".
Taking a look at it, this required a few things:
1. A crash course in using Derby. Dead easy to download, unzip, run. Bit harder to work out where to specify users, properties, and how to configure datasources. There's quite a bit of information out there, but it seems to need some previous level of experience with Derby to make sense of it quickly.
2. OC4J needs to use the derbyclient.jar file to establish a JDBC connection to the Derby server. Now this is similar to the MySql situation -- the derbyclient.jar needs to be placed within OC4J where it can be found by the various classloaders that need it.
The most obvious solution is to put it in the j2ee/home/applib directory, which will make it available to the default application classloader, which should suffice for runtime.
However the thing to keep in mind here is that the applib directory is configured as part of the "global.libraries" shared-library, which is explicitly NOT imported by the ascontrol application. Thus if you want to use ascontrol to configure a DataSource for Derby, you need to make the library available to it as well.
I have a previous post on how this applied to ascontrol/DataSources and MySql, which should explain away this problem as well.
The other options are to publish derbyclient.jar as an explicit named:versioned shared-library and import it wherever its needed. This could be into the default application, a specific application, wherever.
3. Configuring a DataSource. There are several ways to configure a database connection on OC4J -- ConnectionPools with Managed DataSources, or Native DataSources. The doc explains the differences between the two.
Likewise, there are several classes in the derbyclient.jar you can use to connect to a Derby database. Most of the information in googleland shows the use of the org.apache.derby.jdbc.ClientDriver and a simple JDBC URL, and most often being done from within Java code. There are also two additional classes which implement the javax.sql.DataSource and javax.sql.XADataSource interfaces. These seem to be what we should be using for a datasource, and more particularly a datasource for use with XA.
With the classes identified, the next step is to actually create the datasource. This can be done with ascontrol or manually. I initially started using ascontrol, but I ran into some problems. The first was that when I was specifying the Derby DRIVER_URL, which includes the databasename "jdbc:derby://localhost:1521/wombat;create=true", when I tested the connection, I kept getting an error message indicating that the databaseName must be set. Looking at the org.apache.derby.jdbc.ClientDataSource implementation, there's a setter for the database name. To force the setting of the value, I used the <property> configuration setting on the datasource configuration to set the databaseName as follows:
The problem I ran into then, was that with ascontrol if you "test this connection" at this point, it still throws an error saying the databaseName is not set. I don't know for sure, but I think the problem here may be that the supplied properties are not being used when this quick test is done. To get beyond this, click finish to save the connection pool, and then test it from the resulting JDBC resources page.
Another problem I ran into here is that we need a user/password to connect with. The default Derby network server runs without needing authentication. I don't know if this is the correct approach, but I ended up running Derby with a derby.properties file that specified the following:
So that a user "foo" exists and can be used to connect with.
The next issue is that once you have user foo, if you try and do the "test connection" and use the standard sql query "select * from dual" you'll get an error saying the "FOO" schema doesn't exist. I found how to create a schema from some online doc, and used the "ij" utility to create the database "wombat" and the schema "foo".
That finally allowed me to successfully execute a test to verify the connection could be established. Some further reading seemed to indicate there is a default schema called "APP" so perhaps if the test query was modified to explicitly name that schema "select * from APP.dual" maybe that would have worked too. Worth noting is that the table "dual" here does not exist, but I was considering a return error of "table does not exist" as proof that the connection was successfully created.
Once you have the connection pool connecting correctly, then you can wrap it with a datasource which is bound to the JNDI team with a specified name, and hopefully all will be good from then.
For completeness, here is the final data-sources.xml file that shows the final configuration:
Note: as I have alluded to, this may not be the most appropriate way to make use of Derby so please don't read this in that way. I need have to do some more reading, thinking and a lot of testing if I had to do anything more than just prove quickly that it could work with OC4J.
The request, paraphrased was: "I need to use the ClientXADataSource with OC4J to connect to a remote Derby server, but it only seems to connect to localhost".
Taking a look at it, this required a few things:
1. A crash course in using Derby. Dead easy to download, unzip, run. Bit harder to work out where to specify users, properties, and how to configure datasources. There's quite a bit of information out there, but it seems to need some previous level of experience with Derby to make sense of it quickly.
2. OC4J needs to use the derbyclient.jar file to establish a JDBC connection to the Derby server. Now this is similar to the MySql situation -- the derbyclient.jar needs to be placed within OC4J where it can be found by the various classloaders that need it.
The most obvious solution is to put it in the j2ee/home/applib directory, which will make it available to the default application classloader, which should suffice for runtime.
However the thing to keep in mind here is that the applib directory is configured as part of the "global.libraries" shared-library, which is explicitly NOT imported by the ascontrol application. Thus if you want to use ascontrol to configure a DataSource for Derby, you need to make the library available to it as well.
I have a previous post on how this applied to ascontrol/DataSources and MySql, which should explain away this problem as well.
The other options are to publish derbyclient.jar as an explicit named:versioned shared-library and import it wherever its needed. This could be into the default application, a specific application, wherever.
3. Configuring a DataSource. There are several ways to configure a database connection on OC4J -- ConnectionPools with Managed DataSources, or Native DataSources. The doc explains the differences between the two.
Likewise, there are several classes in the derbyclient.jar you can use to connect to a Derby database. Most of the information in googleland shows the use of the org.apache.derby.jdbc.ClientDriver and a simple JDBC URL, and most often being done from within Java code. There are also two additional classes which implement the javax.sql.DataSource and javax.sql.XADataSource interfaces. These seem to be what we should be using for a datasource, and more particularly a datasource for use with XA.
With the classes identified, the next step is to actually create the datasource. This can be done with ascontrol or manually. I initially started using ascontrol, but I ran into some problems. The first was that when I was specifying the Derby DRIVER_URL, which includes the databasename "jdbc:derby://localhost:1521/wombat;create=true", when I tested the connection, I kept getting an error message indicating that the databaseName must be set. Looking at the org.apache.derby.jdbc.ClientDataSource implementation, there's a setter for the database name. To force the setting of the value, I used the <property> configuration setting on the datasource configuration to set the databaseName as follows:
<connection-pool name="DerbyCP">
<connection-factory
factory-class="org.apache.derby.jdbc.ClientXADataSource"
user="foo" password="bar"
url="jdbc:derby://localhost:1527/wombat">
<property name="databaseName" value="wombat"/>
<property name="createDatabase" value="true"/>
</connection-factory>
</connection-pool>
The problem I ran into then, was that with ascontrol if you "test this connection" at this point, it still throws an error saying the databaseName is not set. I don't know for sure, but I think the problem here may be that the supplied properties are not being used when this quick test is done. To get beyond this, click finish to save the connection pool, and then test it from the resulting JDBC resources page.
Another problem I ran into here is that we need a user/password to connect with. The default Derby network server runs without needing authentication. I don't know if this is the correct approach, but I ended up running Derby with a derby.properties file that specified the following:
derby.authentication.provider=BUILTIN
derby.user.foo=bar
So that a user "foo" exists and can be used to connect with.
The next issue is that once you have user foo, if you try and do the "test connection" and use the standard sql query "select * from dual" you'll get an error saying the "FOO" schema doesn't exist. I found how to create a schema from some online doc, and used the "ij" utility to create the database "wombat" and the schema "foo".
That finally allowed me to successfully execute a test to verify the connection could be established. Some further reading seemed to indicate there is a default schema called "APP" so perhaps if the test query was modified to explicitly name that schema "select * from APP.dual" maybe that would have worked too. Worth noting is that the table "dual" here does not exist, but I was considering a return error of "table does not exist" as proof that the connection was successfully created.
Once you have the connection pool connecting correctly, then you can wrap it with a datasource which is bound to the JNDI team with a specified name, and hopefully all will be good from then.
For completeness, here is the final data-sources.xml file that shows the final configuration:
<native-data-source
user="foo" password="bar"
url="jdbc:derby://localhost:1527/wombat;create=true"
data-source-class="org.apache.derby.jdbc.ClientDataSource"
jndi-name="jdbc/DerbyNDS"
name="DerbyNDS">
<property name="databaseName" value="wombat"/>
<property name="createDatabase" value="true"/>
</native-data-source>
<managed-data-source connection-pool-name="DerbyCP" jndi-name="jdbc/DerbyMDS" name="DerbyMDS"/>
<connection-pool name="DerbyCP">
<connection-factory
factory-class="org.apache.derby.jdbc.ClientXADataSource"
user="foo" password="bar"
url="jdbc:derby://localhost:1527/wombat">
<property name="databaseName" value="wombat"/>
<property name="createDatabase" value="true"/>
</connection-factory>
</connection-pool>
Note: as I have alluded to, this may not be the most appropriate way to make use of Derby so please don't read this in that way. I need have to do some more reading, thinking and a lot of testing if I had to do anything more than just prove quickly that it could work with OC4J.
09 December 2008
Replacing Oracle JAX-RPC Libraries
As of the OC4J 10.1.3.4 release, the Oracle WS JAX-RPC libraries have been isolated into their own named/versioned shared-library. This means that they can be selectively removed from the visibility of an application, allowing alternative implementations to be provided as needed:
The shared-library is defined as:
The shared-library is defined as:
Shared Library Name: oracle.ws.jaxrpcThe section in the doc that describes this is here: Using JAX-WS RI
Shared Library Version: 1.1
Parent Name: api
Parent Version: 1.4.0
Modifiable: no
Library Compatible: yes
Code Sources:
/D:/java/oc4j-10134-dev/webservices/lib/jaxr-api.jar
/D:/java/oc4j-10134-dev/webservices/lib/jaxrpc-api.jar
/D:/java/oc4j-10134-dev/webservices/lib/saaj-api.jar
/D:/java/oc4j-10134-dev/webservices/lib/jws-api.jar
20 November 2008
Dependency Injection in Taglibs
Helping with some migration material recently for OC4J --> WLS, a question was asked about whether OC4J 10.1.3.x supported dependency injection with its Tag library implementation.
The taglib.tld file defines the tag:
When the JSP is accessed it successfully displays 12+12=24 which is rendered by the tag library after being calculated via the injected EJB reference.
It's known that OC4J 10.1.3.1+ supports dependency injection in the Web container as described here, but the specifics of whether that extended to tag librarieswas not mentioned.
A subsequent quick test verified that dependency injection does indeed work for tags using the SimpleTag (SimpleTagSupport) and BodyTag (BodyTagSupport).
package sab.testdi.tag;
import java.io.*;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import sab.testdi.ejb.CalcLocal;
public class CalcAdd extends SimpleTagSupport {
@EJB(name="Calc")
CalcLocal calc;
int v1 = 0;
int v2 = 0;
public void setV1(int v1) {
this.v1 = v1;
}
public void setV2(int v2) {
this.v2 = v2;
}
public void doTag() throws JspException, IOException {
PrintWriter out = new PrintWriter(this.getJspContext().getOut());
out.printf("<div style='font-family: courier'>");
if(calc != null) {
out.printf("%s+%s=%s", v1, v2, calc.add(v1, v2));
} else {
out.printf("bugger, calc is null!");
}
out.println("</div>");
}
}
The taglib.tld file defines the tag:
<?xml version = '1.0' encoding = 'windows-1252'?>And finally, a JSP can use it by importing the JAR file containing the tag libraru into the WEB-INF/lib directory (where it is nicely auto-discovered) and making a call to the <calc:add .../> tag.
<taglib xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0"
xmlns="http://java.sun.com/xml/ns/j2ee">
<display-name>calc</display-name>
<tlib-version>1.2</tlib-version>
<short-name>calc</short-name>
<uri>/webapp/calc</uri>
<tag>
<description>A short description...</description>
<display-name>add</display-name>
<name>add</name>
<tag-class>sab.testdi.tag.CalcAdd</tag-class>
<body-content>empty</body-content>
<attribute>
<name>v1</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>v2</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<example><calc:add v1="100" v2="25"/></example>
</tag>
</taglib>
<!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="/webapp/calc" prefix="calc"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<title>Index</title>
</head>
<body style="font-family: arial">
<h2>Testing Taglib Dependency Injection</h2>
<p>
<calc:add v1="12" v2="12"/></p>
</body>
</html>
When the JSP is accessed it successfully displays 12+12=24 which is rendered by the tag library after being calculated via the injected EJB reference.
18 November 2008
Configuring shared-libraries settings post deployment
With the introduction of the shared-library mechanism in OC4J 10.1.3.x, it is possible to configure the set of libraries that an application has access to. This is done at the application level using the tag to include a named shared-library, or its counterpart, to remove a library from the view of the application.
These settings are made in the OC4J specific orion-application.xml deployment descriptor for the application, typically either as a hard-coded entry in the packaged EAR file that is being deployed, or they are set during the deployment process using the Class Loading Task in the ASC console.
In the current releases, there are no ways to easily change these settings once the application has been deployed. One approach that has been used is to perform a redeployment operation of the application and make the change via the ASC console. Obviously this requires a redeployment to be performed. While you can also manually edit the resulting orion-application.xml file to add/remove/change the settings, this provides no validation that the settings are correct.
To address this, for the next patch release of OC4J (10.1.3.5) we are looking to add a couple of new shared-library commands to the admin_client.jar utility to operate on existing, deployed applications. These commands will allow you to perform add or delete operations on either of the or configuration elements.
As an example, lets say you have an application in which you wish to use the Apache Xerces parser instead of the Oracle XML parser. This change can be performed during deployment as described here: http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-swapxmlparser/doc/readme.html
But! When you test your application, it throws an Exception and you eventually realise that you forgot to make the change to the shared-libraries during the deployment of the application. The Oracle XML parser is still being used.
Using the new commands you would be able to change this on the deployed application as follows:
>java -jar admin_client.jar .... -addRemoveInheritedSharedLibrary -appName myapp -name oracle.xml
>java -jar admin_client.jar .... -addImportSharedLibrary -appName myapp -name apache.xml -minVersion 2.7 -maxVersion 2.7
These settings are made in the OC4J specific orion-application.xml deployment descriptor for the application, typically either as a hard-coded entry in the packaged EAR file that is being deployed, or they are set during the deployment process using the Class Loading Task in the ASC console.
In the current releases, there are no ways to easily change these settings once the application has been deployed. One approach that has been used is to perform a redeployment operation of the application and make the change via the ASC console. Obviously this requires a redeployment to be performed. While you can also manually edit the resulting orion-application.xml file to add/remove/change the settings, this provides no validation that the settings are correct.
To address this, for the next patch release of OC4J (10.1.3.5) we are looking to add a couple of new shared-library commands to the admin_client.jar utility to operate on existing, deployed applications. These commands will allow you to perform add or delete operations on either of the
As an example, lets say you have an application in which you wish to use the Apache Xerces parser instead of the Oracle XML parser. This change can be performed during deployment as described here: http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-swapxmlparser/doc/readme.html
But! When you test your application, it throws an Exception and you eventually realise that you forgot to make the change to the shared-libraries during the deployment of the application. The Oracle XML parser is still being used.
Using the new commands you would be able to change this on the deployed application as follows:
>java -jar admin_client.jar .... -addRemoveInheritedSharedLibrary -appName myapp -name oracle.xml
>java -jar admin_client.jar .... -addImportSharedLibrary -appName myapp -name apache.xml -minVersion 2.7 -maxVersion 2.7
17 November 2008
JEE5 web-app declaration
I seem to have trouble finding the correct definition of the web-app tag for JEE5/Servlet2.5 modules.
So for nothing more than a readily available memo to myself, here it is:
The schema is located here: http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd
So for nothing more than a readily available memo to myself, here it is:
<web-app
version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
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">
The schema is located here: http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd
XMLSchemas for WebLogic Server
The first set of XSD files for WebLogic Server have just been posted to the Oracle XSD hosting location: http://xmlns.oracle.com/weblogic.
The index page allows you to drill down into the version of WebLogic Server you are interested in, and ultimately locate the component specific XSD file.
For example, the JDBC Data Source XSD is located at: http://xmlns.oracle.com/weblogic/jdbc-data-source/1.0/jdbc-data-source.xsd
The index page allows you to drill down into the version of WebLogic Server you are interested in, and ultimately locate the component specific XSD file.
For example, the JDBC Data Source XSD is located at: http://xmlns.oracle.com/weblogic/jdbc-data-source/1.0/jdbc-data-source.xsd
05 November 2008
Checking if FastSwap is enabled
In doing some work with the FastSwap feature of WebLogic Server recently, I wanted to be able to display whether FastSwap was enabled for the application.
I used the small hack below to determine whether FastSwap is enabled or not for the application. This examines the current ClassLoader that is being used and compares it with the FastSwap enabled ClassLoader.
Another interesting area was to observe how the class name changed as the underlying class itself changed and FastSwap did its funky thing. I noticed that the second frame on the Thread stack contains the FastSwap modified classname. Grabbing that, you can keep track of the class name changes over time to display.
As the class changes over time, the names will look like the below:
I used the small hack below to determine whether FastSwap is enabled or not for the application. This examines the current ClassLoader that is being used and compares it with the FastSwap enabled ClassLoader.
If the classloader name changes in a future release, then of course this would break ... but it serves the purpose currently on WLS 10.3.
private final String fastSwapLoader = "com.bea.wls.redef.RedefiningClassLoader";
...
private boolean isFastSwapEnabled() {
return Thread.currentThread().getContextClassLoader().getClass().getName().equals(fastSwapLoader);
}
Another interesting area was to observe how the class name changed as the underlying class itself changed and FastSwap did its funky thing. I noticed that the second frame on the Thread stack contains the FastSwap modified classname. Grabbing that, you can keep track of the class name changes over time to display.
private String determineClassName() {
return Thread.currentThread().getStackTrace()[1].getClassName();
}
As the class changes over time, the names will look like the below:
- sab.demo.fastswap.web.TestServlet_beaVersion0_1
- sab.demo.fastswap.web.TestServlet_beaVersion1_11
- sab.demo.fastswap.web.TestServlet_beaVersion2_12
- ...
Starting WebLogic Server instance with local JMX access enabled
Needing to connect to a WLS instance with JConsole to view/use the MBeans?
Me too.
The simplest way I found to do it was to to add an entry to the setDomainEnv.cmd file for the specific managed instance:
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dcom.sun.management.jmxremote
When you then run the managed instance, the setDomainEnv.cmd file is called and the additional property is added to the JVM when it is launched.
This is covering the case of starting the server instance from the command line -- if you are using Node Manager, then you'll need to set this in the configuration script that is used by the nodemanager.
Me too.
The simplest way I found to do it was to to add an entry to the setDomainEnv.cmd file for the specific managed instance:
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dcom.sun.management.jmxremote
When you then run the managed instance, the setDomainEnv.cmd file is called and the additional property is added to the JVM when it is launched.
This is covering the case of starting the server instance from the command line -- if you are using Node Manager, then you'll need to set this in the configuration script that is used by the nodemanager.
Subscribe to:
Posts (Atom)