27 May 2009

Finding MBean names using Groovy Collections

Needed to do me some searching of the WebLogic Server MBean runtime domain looking for MBeans that matched some part of a specified string -- it's name, it's type, etc.

This was the best I could do in Groovy:
def matches(con, name) { 
con.queryNames(new ObjectName("*:*"), null).findAll{
it.toString() =~ name
}.join("\n")
}
which can be called such as:
println matches(con, "Domain")
to produce output such as:
com.bea:ServerRuntime=examplesServer,Name=weblogic.logging.DomainLogBroadcasterClient,Type=MinThreadsConstraintRuntime
com.bea:ServerRuntime=examplesServer,Name=DomainLog,Type=WLDFFileArchiveRuntime,WLDFRuntime=WLDFRuntime
com.bea:ServerRuntime=examplesServer,Name=DomainLog,Type=WLDFDataAccessRuntime,WLDFAccessRuntime=Accessor,WLDFRuntime=WLDFRuntime
com.bea:ServerRuntime=examplesServer,Name=weblogic.logging.DomainLogBroadcasterClient,Type=WorkManagerRuntime
com.bea:Name=wl_server,Type=Domain
OK, what about checking for multiple names at once?
def matchesAny(con, map) { 
map.collect() { name ->
matches(con, name)
}.join("\n")
}
which can be called such as:
println matchesAny(con, ["Domain", "Kodo"])
to produce output such as:
com.bea:ServerRuntime=examplesServer,Name=weblogic.logging.DomainLogBroadcasterClient,Type=MinThreadsConstraintRuntime
com.bea:ServerRuntime=examplesServer,Name=DomainLog,Type=WLDFFileArchiveRuntime,WLDFRuntime=WLDFRuntime
com.bea:ServerRuntime=examplesServer,Name=DomainLog,Type=WLDFDataAccessRuntime,WLDFAccessRuntime=Accessor,WLDFRuntime=WLDFRuntime
com.bea:ServerRuntime=examplesServer,Name=weblogic.logging.DomainLogBroadcasterClient,Type=WorkManagerRuntime
com.bea:Name=wl_server,Type=Domain
com.bea:ServerRuntime=examplesServer,Name=reviewService,ApplicationRuntime=ejb30,Type=KodoQueryCompilationCacheRuntime,EJBComponentRuntime=domain.jar,KodoPersistenceUnitRuntime=reviewService
com.bea:ServerRuntime=examplesServer,Name=reviewSession,ApplicationRuntime=ejb30,Type=KodoQueryCompilationCacheRuntime,EJBComponentRuntime=domain.jar,KodoPersistenceUnitRuntime=reviewSession
com.bea:ServerRuntime=examplesServer,Name=reviewService,ApplicationRuntime=ejb30,Type=KodoPersistenceUnitRuntime,EJBComponentRuntime=domain.jar
com.bea:ServerRuntime=examplesServer,Name=reviewSession,ApplicationRuntime=ejb30,Type=KodoPersistenceUnitRuntime,EJBComponentRuntime=domain.jar
Easy peasy and served my needs.

LOVE THE GROOVY

30 April 2009

WLS and JConsole

Here's a script I used to connect JConsole to a WLS 10.3.x instance.

Thanks to James Bayer for his blog on this too.

@setlocal

rem runtime_url=service:jmx:rmi:///jndi/iiop://localhost:7001/weblogic.management.mbeanservers.runtime
set domain_url=service:jmx:rmi:///jndi/iiop://localhost:7001/weblogic.management.mbeanservers.domainruntime

set JAVA_HOME=d:\bea\jrockit_160_05_R27.6.2-20
set WLS_HOME=d:\bea\wlserver_10.3\server

set JCONSOLE_CLASSPATH
set JCONSOLE_CLASSPATH=%JCONSOLE_CLASSPATH%;%JAVA_HOME%\lib\jconsole.jar
set JCONSOLE_CLASSPATH=%JCONSOLE_CLASSPATH%;%JAVA_HOME%\lib\tools.jar

set WLS_CLASSPATH=
set WLS_CLASSPATH=%WLS_CLASSPATH%;%WLS_HOME%\lib\wljmxclient.jar
set CLASSPATH=%JCONSOLE_CLASSPATH%;%WLS_CLASSPATH%

set PROPS=
set PROPS=%PROPS% -J-Djmx.remote.proto.provider.pkgs=weblogic.management.remote
set PROPS=%PROPS% -J-Djava.class.path=%CLASSPATH%

jconsole %PROPS%

@endlocal



29 April 2009

WLS Javadoc

Took me a while to find this. Turns out its right there on the developers doc page but it took me a few scans to call it out.

For future reference, here's the direct link:

WLS 10.3 Javadoc

23 April 2009

Ganymede

Downloaded. Unzipped.  Running.


Downloading Oracle Enterprise Pack for Eclipse

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.

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?

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:

<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:
Shared Library Name:    oracle.ws.jaxrpc
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
The section in the doc that describes this is here: Using JAX-WS RI

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.

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'?>
<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>
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.
<!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