18 June 2009

Weblogic Server DataSource Using TNS Names

As of Oracle JDBC 10.2, it's possible to establish a connection with the thin driver using tnsnames.

http://download.oracle.com/docs/cd/B19306_01/java.102/b14355/urls.htm#BEIDIJCE

This allows you to store your database server details in an external tnsnames.ora file, which you then reference from the JDBC connection URL.

To use this with a Weblogic Server DataSource, try the following:

  1. Create a tnsnames.ora file with the required connection details and store it in a file that is accessible to the WLS instance:
    TEST =
    (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = testserver)(PORT = 1521))
    (CONNECT_DATA =
    (SERVER = DEDICATED)
    (SERVICE_NAME = test.au.oracle.com)
    )
    )

  2. Edit the setDomainEnv script for your domain and add the following System property
    -Doracle.net.tns_admin=<PATH_TO_TNS_NAMES_FILE>

  3. Create a DataSource and specify the connection URL to use the TNS names entry:
      <name>basic</name>
    <jdbc-driver-params>
    <url>jdbc:oracle:thin:@TEST</url>
    <driver-name>oracle.jdbc.xa.client.OracleXADataSource</driver-name>
    <properties>
    <property>
    <name>user</name>
    <value>banker</value>
    </property>
    </properties>
    <password-encrypted>{AES}fOJ/qlGxQjpdSiPODvxxilPHy/VuQe8yXggSSh1Lw4c=</password-encrypted>
    </jdbc-driver-params>

When the connection pool needs to create connections, it will lookup and use the specified TNS names entry from tnsnames.ora file in the directory specified oracle.net.tns_admin property.

12 June 2009

Displaying Server details in OEPE

When you have a Server defined in your OEPE environment, double-clicking on the icon presents the configuration page as shown below. For a single page, it's quite rich in detail, giving you access to the domain directories (assuming its local), the properties of the Server connection itself, how publishing is performed, and even a list of deployed modules in the domain.



Clicking on the "Open WebLogic Server Console" link opens the WLS Console directly within the Eclipse environment, where you can manage the server and all its resources as normal.

Note:
I found that when doing this with WLS 10.3.x caused any publishing events to fail since the WLS Console automatically acquires the edit lock in development mode, which prevents Eclipse from performing any application updates. Seems you'd need to to configure the use of Use Lock and Edit mode if you wanted to make use of this.

01 June 2009

WebLogic Schema Definitions

WebLogic Schema Definitions are available from this Oracle site:

http://www.oracle.com/technology/weblogic/index.html

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.