03 December 2009

WebLogic Server does SCA

Tech preview of SCA in WLS 10.3.2:
http://blogs.oracle.com/WebLogicServer/2009/12/getting_started_with_weblogic.html

13 October 2009

Exploring EclipseLink @OptimisticLocking

Been a while since I've had some fun with JPA, so I decided to spend a little time with it today.

I created a very simple domain model (Employee --> LeaveRecord) to use.



Since I was just intent of doing some quick testing, instead of following the usual route of creating an EJB session facade to expose the @Entity objects, and then exercising that from a client to test things out, I simply created some JUnit4 @Test cases to act as the test clients. These @Test cases exercised the @Entity objects from outside the container, so it was actually a very easy way to go.





One thing I'd never looked at much was the EclipseLink specific annotations, so I decided to take a quick peek around there for something interesting to test. A quick peruse of the EclipseLink documentation drew me to the @OptimisticLocking annotation.  How could you not be optimistic with that!

The goal of the @OptimisticLocking annotation is to direct EclipseLink to use an optimistic locking strategy for the @Entity, directing it to the current property values from the object it is persisting against the data currently in the database to ensure it hasn't changed since it was last read. 

There are several different options available, so I took a look at the differences between the OptimisticLockingType.ALL_COLUMNS and the OptimisticLockingType.CHANGED_COLUMNS options.

The @OptimisticLocking annotation is specified on the POJO.

  @Table(name = "EMPLOYEES")
  @OptimisticLocking(type=OptimisticLockingType.ALL_COLUMNS)
  public class Employee implements Serializable {
      ...
  }
 
Doing simple reads and updates of the Employee @Entity with the eclipselink.logging.level set to FINEST shows the SQL that is created when the different types are applied.

@OptimisticLocking(type=OptimisticLockingType.ALL_COLUMNS)
Connection(26174809)--UPDATE EMPLOYEES SET VACATION_HOURS = ? 
  WHERE ((EMPLOYEE_ID = ?) AND 
  (((((EMAIL_ADDRESS = ?) AND 
      (FIRST_NAME = ?)) AND 
      (LAST_NAME = ?)) AND 
      (SALARY = ?)) AND 
      (VACATION_HOURS = ?)))
   bind => [999, 1, jack.rooster@anon.org1, Jack1, Rooster1, 1.0, 1]

In this configuration, all the fields of the @Entity are contained in the WHERE clause of the UPDATE statement.

@OptimisticLocking(type=OptimisticLockingType.CHANGED_COLUMNS)
Connection(2554341)--UPDATE EMPLOYEES SET VACATION_HOURS = ? 
  WHERE ((EMPLOYEE_ID = ?) AND (VACATION_HOURS = ?))
  bind => [999, 1, 1]

In this configuration, only the updated fields of the @Entity are contained in the WHERE clause of the UPDATE statement.

After testing the @OptimisticLocking annotation and observing that I worked as expected in my test environment, the next step was to test what happens when a change is made to an object after it has been read, but before it is updated.

The flow is essentially this:

  T1 --> read employee 1
  T1 --> create and start T2
    T2 --> read employee 1
    T2 --> update employee 1
    T2 --> persist employee 1
  T1 --> update employee 1
  T1 --> persist employee 1  *expect OptimisticLockingException*

The @Test case below represents this sequence.

@Test(expected = RollbackException.class, timeout = 20000)
public void checkOptimisticLocking() throws Exception {

    Employee pre = employeePM.find(Employee.class, Long.valueOf(1));

    // do the separate thread update of the specified employee with value
    EmployeeTestOptimisticLockingHelper t = 
        new EmployeeTestOptimisticLockingHelper(1L, -999L);

    t.start();
    t.join(10000);

    // Now do the local the update
    // should throw OptimisticLockException
    employeePM.getTransaction().begin();
    pre.setVacationHours(999L);
    employeePM.getTransaction().commit();
}

The EmployeeTestOptimisticLockingHelper is a separate class that is executed via another Thread.  This allows it to perform the change using a separate EntityManager.

public class EmployeeTestOptimisticLockingHelper extends Thread {

    private Long id;
    private Long newval;

    public EmployeeTestOptimisticLockingHelper(Long id, Long newval) {
        this.id = id;
        this.newval = newval;
    }

    @Override
    public void run() {
        EntityManager em = null;
        try {
            em = Persistence.createEntityManagerFactory("CompanyUnit")
                            .createEntityManager();
            Employee emp = em.find(Employee.class, id);
            em.getTransaction().begin();
            emp.setVacationHours(newval);
            em.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            em.close();
            interrupt();
        }
    }
}

When this @Test is executed, it results in the following exception being thrown, demonstrating that the specified @OptimisticLocking model is working as expected.

[EL Finer]: 2009.10.13 14:54:43.796--ClientSession(14031599)--Connection(26174809)--rollback transaction
[EL Warning]: 2009.10.13 14:54:43.796--UnitOfWork(26953544)--javax.persistence.OptimisticLockException: Exception [EclipseLink-5006] (Eclipse Persistence Services - 1.0.2 (Build 20081024)): org.eclipse.persistence.exceptions.OptimisticLockException
Exception Description: The object [Employee 1 Jack1 Rooster1 jack.rooster@anon.org1 999 $1.0] cannot be updated because it has changed or been deleted since it was last read. 
Class> sab.demo.company.domain.Employee Primary Key> [1]
 at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:480)
 at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1330)
 at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:159)
 at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1002)
 at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:84)
 at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
 at sab.demo.testdomains.EmployeeTest.checkOptimisticLocking(EmployeeTest.java:149)

And the JUnit runner shows the @Test passes as expected, since it is configred to expect the wrapper javax.persistence.RollbackException to occur.



07 October 2009

Getting samples schema to run against an Oracle DB

The samples domain that is able to be optionally created with a WebLogic Server installation provides a wealth of useful examples, covering core JavaEE APIs through to an full sample application called MedRec.

By default, the samples domain installs and uses a PointBase database to host its application data, which allows it to work immediately after installation with no additional requirements to install, configure a database.

It probably goes without saying, but there is interest in making the samples also work with an Oracle database.

When the samples domain is created, it provides its own set of online documentation that describes how to configure, install and use the various samples.

One section in the doc notes how to install the sample schema against an Oracle database, which ultimately results in the execution of the demo.ddl file against the specified Oracle database instance.

>ant db.setup.oracle


I just tried it against an Oracle XE (10.2) database I have lying around and noticed some problems when it executed, based on inserting date format data into several of the tables used by the MedRec application.

[sql] Failed to execute:   INSERT INTO patient (id,first_name,middle_name,last_name,dob,gender,ssn,address_id,phone,email) VALUES (101,'Fred','I','Winner','1965-03-26','Male','123456789',101,'4151234564','fred@golf.com')
[sql] java.sql.SQLDataException: ORA-01861: literal does not match format string

[sql] Failed to execute:   INSERT INTO record (id,pat_id,phys_id,record_date,vital_id,symptoms,diagnosis,notes) VALUES (101,101,102,'1999-06-18',101,'Complains about chest pain.','Mild stroke.  Aspiran advised.','Patient needs to stop smoking.')
[sql] java.sql.SQLDataException: ORA-01861: literal does not match format [sql] 

[sql] Failed to execute:   INSERT INTO prescription (id,pat_id,date_prescribed,drug,record_id,dosage,frequency,refills_remaining,instructions) VALUES (101,101,'1999-06-18','Advil',101,'100 tbls','1/4hrs',0,'No instructions')
[sql] java.sql.SQLDataException: ORA-01861: literal does not match format string


To workaround this, I found that by editing the $WLS_HOME\wlserver_10.3\samples\server\examples\src\examples\common\demo.ddl and appending the DATE function to the respective insert statements, the demo.ddl script executed without error and the data was inserted correctly.

Here are examples of the row inserts that have been modified:

INSERT INTO patient (id,first_name,middle_name,last_name,dob,gender,ssn,address_id,phone,email) 
VALUES 
(101,'Fred','I','Winner',DATE'1965-03-26','Male','123456789',101,'4151234564','fred@golf.com');

INSERT INTO record (id,pat_id,phys_id,record_date,vital_id,symptoms,diagnosis,notes) 
VALUES 
(101,101,102,DATE'1999-06-18',101,'Complains about chest pain.','Mild stroke.  Aspiran advised.','Patient needs to stop smoking.');

INSERT INTO prescription
(id,pat_id,date_prescribed,drug,record_id,dosage,frequency,refills_remaining,instructions) VALUES
(101,101,DATE'1999-06-18','Advil',101,'100 tbls','1/4hrs',0,'No instructions');

Once that was done, the demo.ddl executed successfully and the schema was created in the specified Oracle database.

25 September 2009

14 September 2009

Using Identity Based Connection Pooling with WebLogic Server

From an OTN how-to I recently created:

Using Identity Based Connection Pooling with WebLogic Server

The typical model of interaction an application server has with a database is through the use of datasources.

A datasource is an entity that is configured with appropriate information to allow it to create and manage connections with a database, and to hand these out to applications when they request them. A datasource typically creates pools of connections for effiency purposes and shares these amongst applications that make use of it.

In the typical datasource use case, all the connections the datasource creates use the same username and password. This results in all access to the database being performed using the same database credentials. In most cases this is perfectly acceptable and handled as part of the overall application architecture when needing to dealing with shared, partioned data.

For some rare cases, requirements can exist where it’s necessary to preserve the application user identity in some form all the way down to the database. This could be for the purposes of restricting information access, establishing audit trails, resource scheduling based on user context, etc.

To support these two different usage requirements, WebLogic Server supports two different types of connection pools through its datasource implementation:
  • Homogeneous: Regardless of the current user of the application, all connections in the pool use the same security credentials to access the DBMS.
  • Heterogeneous: Allows applications to use a JDBC connection with a specific DBMS credential by pooling physical connections with different DBMS credentials.
[See full article on OTN: http://www.oracle.com/technology/products/weblogic/howto/identity-pools/index.html]

03 September 2009

Switching Between JRockit and Sun JDK with WebLogic Server

Need to swap between JRockit and the Sun JDK when starting your WebLogic Server instance?

Looking at the start scripts $DOMAIN_HOME/bin/setDomainEnv.cmd, I just realized that this operational task is basically taken care of in the scripts we have.

To swap between the Sun JDK and JRockit to launch a WLS instance, all you need to do is set the JAVA_VENDOR environment variable to either "Sun" or "Oracle" and the scripts will take of launching WLS using the specified JDK.

Snippets from setDomainEnv.cmd:
set BEA_JAVA_HOME=d:\wls1031\jrockit_160_05_R27.6.2-20
set SUN_JAVA_HOME=d:\wls1031\jdk160_11

if "%JAVA_VENDOR%"=="Oracle" (
set JAVA_HOME=%BEA_JAVA_HOME%
) else (
if "%JAVA_VENDOR%"=="Sun" (
set JAVA_HOME=%SUN_JAVA_HOME%
) else (
set JAVA_VENDOR=Sun
set JAVA_HOME=d:\wls1031\jdk160_11
)
)

Where JAVA_HOME is then used by startWebLogic.cmd script when it launches the WLS instance to identify the JDK to use.

Snippets from startWebLogic.cmd
%JAVA_HOME%\bin\java %JAVA_VM% %MEM_ARGS% 
-Dweblogic.Name=%SERVER_NAME% 
-Djava.security.policy=%WL_HOME%\server\lib\weblogic.policy 
%JAVA_OPTIONS% 
%PROXY_SETTINGS% 
%SERVER_CLASS%

With this information at hand, then switching between the two different JDKs is as simple as setting an environment variable before launching WebLogic Server.

Using JRockit:
>set JAVA_VENDOR=Oracle
>startWebLogic.cmd
...
d:\wls1031\JROCKI~1.2-2\bin\java -jrockit -Xms512m -Xmx512m -Dweblogic.Name=AdminServer ...

And just as easy to switch back to Sun. Note here that you could just unset the JAVA_HOME environment variable, which will set the script to use whatever default was configured when the domain was created.

Using Sun JDK:
>set JAVA_VENDOR=Sun
>startWebLogic.cmd
...
d:\wls1031\JDK160~1\bin\java -client -Xms256m -Xmx512m -Dweblogic.Name=AdminServer ...

WebLogic Server Startup and Shutdown Classes

WebLogic Server supports the use of server level startup and shutdown (SU/SD) classes, which are invoked by the server when it is starting up, and conversely when it is shutting down.

The initial implementation of this functionality (not sure of the release but circa 6.x I believe) required the SU/SD classes to implement proprietary WebLogic Server interfaces:
  • weblogic.common.T3StartupDef
  • weblogic.common.T3ShutdownDef
As of WebLogic Server 9.0, these interfaces were marked as deprecated.

It appears that with the introduction of the new application lifecycle listeners feature at the same time, this has resulted in reduced visbility of the new POJO based SU/SD class approach in the documentation.

So here's a brief explanation.

With the deprecation of the earlier SU/SD interfaces, a new and simpler POJO based was introduced for SU/SD classes. This requires only that a SU/SD class only has to have a static main(String args[]) method, which the server will invoke after instantiating the class. No WLS specific interfaces are needed any longer. Any arguments that were configured for the SU/SD class configuration are passed to it via the String[] args parameter.

The POJO based SU/SD class still follows all the same deployment and configuration steps used by the previous model -- the class needs to be made available on the server classpath, the SU/SD class is configured via the console with the requisite parameters and settings, and ultimately stored as an entry in config.xml.

Startup Class:
package sab.demo.utils;

public class StartupMain {
/**
* @param args
*/
public static void main(String[] args) {

log(StartupMain.class.getName() + "::main");
log("Arguments::");
for(int i=0;args!=null && i<args.length;i++) {
log("  arg[" + i + "]: " + args[i]);
}
}

private static void log(String msg) {
System.out.printf("  --> [SAB]: %s\n", msg);
}
}


WLS Console:


config.xml:
<startup-class>
<name>StartupMain</name>
<target>AdminServer</target>
<deployment-order>1000</deployment-order>
<class-name>sab.demo.utils.StartupMain</class-name>
<arguments>arg1 arg2 arg3</arguments>
<failure-is-fatal>false</failure-is-fatal>
<load-before-app-deployments>false</load-before-app-deployments>
<load-before-app-activation>true</load-before-app-activation>
</startup-class>

28 August 2009

OC4J 10.1.3.5 Released


We published OC4J 10.1.3.5 to OTN this week.

This is a maintenance release, but it has a sprinkling of new features that had been in the works for a while and have now made it into an official OC4J release.

Download location:

http://www.oracle.com/technology/software/products/ias/htdocs/utilsoft.html

Updated Documentation:


http://download.oracle.com/docs/cd/E14101_01/index.htm


Release Notes:

http://download.oracle.com/docs/cd/E14101_01/doc.1013/e15342/oc4j.htm

New Feature List:

http://download.oracle.com/docs/cd/E14101_01/doc.1013/e15342/oc4j.htm#BDCCBAFD

I really like the small set of new features that have been added.

My pick of them, is probably the Peek utility. Peek provides a nice Web based front end for singing and dancing, all powerful, classloading functionality we've had in OC4J 10.1.3.x since its first dot zero release. Peek lets you drive easily around the classloading environment, visualizing the loader tree and letting you to drill down into it to see code-sources, packages, classes, etc. It also lets you execute the wide set of classloader queries we provide, directly from a Web browser. Really neat stuff.

There are also a set of new commands added to the admin_client utility, to support actions such as getting a listing of all deployed applications/web bindings, importing (and removing) shared libraries into applications, and a restart app command. Nice additions.

If you are still using OC4J and haven't yet moved over to the world of WebLogic Server, I reckon checking out OC4J 10.1.3.5 would be worth your time.

24 August 2009

WebLogic Server in the Amazon EC2 Cloud

I've long been wanting to try the WebLogic Server AMI image on the Amazon EC2 Cloud, but haven't yet had a chance to do it.

The description for how to get started is here:

http://www.oracle.com/technology/tech/cloud/pdf/wlsami_ref.pdf

The Amazon Machine Image (AMI) repository where WebLogic Server 10.3 is here:

http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=205

Has anyone out there given this a shot? What were your thoughts, how did it go?

20 August 2009

Hosted WebLogic Server Documentation Changes

Just received a note regarding changes that are occuring to the WebLogic Server online documentation.

As of Friday, August 7, 2009, all BEA product documentation currently available on the BEA online documentation site (edocs.bea.com) will be available on the Oracle Technology Network (OTN).

Please note: Effective Friday, August 31, 2009, at 5:00pm PDT, the BEA online documentation site will be decommissioned.

The OTN URL for legacy WLS release documentation is:

http://www.oracle.com/technology/documentation/weblogic_server.html

The OTN URL for legacy BEA release documentation is:

http://www.oracle.com/technology/documentation/bea_doc_index.html

History, Forms, JavaBeans and PJCs

Just came across an old document I'd written about using JavaBeans and Pluggable Java Components in Oracle Forms applications.

http://www.oracle.com/technology/products/forms/pdf/269054.pdf

It's quite funny rediscovering old stuff that you'd worked on!

03 August 2009

Link to Oracle JDBC Javadoc

Maybe it's just me, but the javadoc for the Oracle JDBC drivers is not easily located on the Oracle documentation sites.

Finally, I found this JDBC page, which contains direct links to the javadoc for the various Oracle JDBC versions.

Oracle JDBC site

Oracle JDBC 11g R1 Javadoc

Oracle JDBC 10g R2 Javadoc

03 July 2009

WebLogic Server 11g (10.3.1) Released

Now that WebLogic Server 11g (10.3.1) has been released, looking forward to writing a few blogs again about topics of interest. I look after the PM work for WebLogic Server across the Web, EJB, JDBC, JTA and JCA areas. So those will be my main topics of interest I suspect.

Download WebLogic Server 11g from here:
http://www.oracle.com/technology/software/products/ias/htdocs/wls_main.html

The direct view to the WebLogic Server doc set in the revamped doc layout is here:
http://download.oracle.com/docs/cd/E12839_01/wls.htm

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.