Some 'more, in-depth' information on Oracle BPEL PM, ESB and other SOA, day2day things

Friday, April 30, 2004

WebServices and Security - a cool workshop :)

Yesterday a helped one of my colleques @ a ct. that is very interested on our j2ee stack, specially ADF.

Webservice tech, is something they use since years, and therefor the main question of yesterday was, how to make them secure ...

Think, this was a great thing and being there, hearing some stuff from the .net people about how they gonna use webservices - and a great opp'y showing them how easily we can access their .NET - webservices with JDEV-generated client stubs.

Mike wrote a great tutorial about how you can secure your webservices - join him on his blog Lehmann blogger

Having questions? Feedback me on this entry Clemens Utschig

Friday, April 23, 2004

"REAL HIGH AVAILABILITY" - Java with RAC and OCI

Thinking about really securing your application, even to stay alive, when the DB-Server goes down? - Then give our RAC (Real Application Cluster) a try!

Yesterday, at one of my ct's, we connected a J2EE Application (built upon our BC4J framework) on iAS903 to ct's RAC for enabling the failover mechanism Oracle's RAC provides, and securing their application against downtimes.

So what to do, to use this feature too? (besides having a running RAC :-) )

The only configuration thing, that has to be done, consists of changing the connection String (in the application, or Datasource) to use OCI and use an existing TNS-Entry from TNSNAMES.ora - that is properly configured to do the failover .. (so when doing this on iAS, the shipped version is enough to be used!)

In the application:
jdbc:oracle:oci:@<yourName>

In TNSNAMES.ora of the used OracleClient:
 #Configure a single clusterwide service with
 # load-balance, failover and TAF enabled.
 <yourName> =
    (DESCRIPTION =
      (ADDRESS_LIST =
      (LOAD_BALANCE = yes)
      (FAILOVER = on)
      (ADDRESS = (PROTOCOL = TCP)(HOST = <your host for instance1>)(PORT = <yourPort>))
      (ADDRESS = (PROTOCOL = TCP)(HOST = <your host for instance2>)(PORT = <yourPort>))
    )
    (CONNECT_DATA =
     (SERVICE_NAME = <your service name>)
     (FAILOVER_MODE = (TYPE = SELECT)(METHOD = BASIC)(RETRIES = 20)(DELAY = 20))
    )
   )


Without any (code) modifications to the application, we tested failover, and it worked perfectly, nearly no time, the Cluster Manager needed, to relink the existing DBConnection to the other running node. Just saying great ! :)

Having questions? Feedback me on this entry Clemens Utschig

Thursday, April 22, 2004

OCI @ iAS903:
Solving the miracles 'round there (getting UnsatisfiedLinkError - no ocijdbc9)

.. and once again .. some more stuff on this oci thing -
specially needed when you attempt to use OCI in a J2EE App, deployed into your own container on iAS.

1) Stop opmn (by using "$ORACLE_HOME/opmn/bin/opmnctl stop")

2) open opmn.xml (in $ORACLE_HOME/opmn/conf)

3) search for an head-entry representing your container .. (for OC4J__Demos it look like the following)
    <oc4j instanceName="OC4J_Demos" gid="OC4J_Demos">

4) add the following entry between this tags (right before </oc4j>)
    <environment>
      <prop name="LD_LIBRARY_PATH" value="/home/oracle/9iAS903/lib"/>
    </environment>


    where LD_LIBRARY_PATH MUST point to $ORACLE_HOME/lib !

5) After this go to $ORACLE_HOME/dcm/bin and do
    dcmctl updateconfig -ct opmn

6) restart opmn by using opmnctl startall , that starts all containers/components and it will work now properly :)

Having questions? Feedback me on this entry Clemens Utschig

Thursday, April 15, 2004

JDeveloper 904: All fixes from 9034 are in too!

Today,
we just had (as of some performance issues) the need for profiling a Java1.4 app - which is just possible in JDev904 and higher ..
As a lot of fixes, concerning ViewLinkConsistency, have been done in 9034, i was not too sure if they would be in 904 either, as 904 is more or less, just the corresponding 903x JDev version that supports Java1.4 compiling, debugging with embedded ojc and ojvm.

After a quick "check-mail" with development, to our best knowledge all the 9034 fixes are included in the 904 JDeveloper release too, great ! :-)

Having questions? Feedback me on this entry Clemens Utschig

Wednesday, April 14, 2004

BC4J 9034: REACTIVATION OF EMPTY STRING PARAM ('''') IN WHERECLAUSE FAILS

Sitting @ customer, we discovered a strange behaviour, when using expert-mode VO*s, that have binding params.

Consider the following snippet:
  // set the second param to an empty String
  mDeptView.setWhereClauseParam(1, ""); -> "" is the same as new String ("")

when passivating this VO after executing the query, the snapshot (for the argument in the where-clause, that you filled with an empty String) will look like this:
  [CDATA[]

On reactivation time - when using SessionCookie.useApplicationModule(), this will cause a NPE in oracle.jbo.server.ViewObjectImpl.

When you encounter this issue, the easiest thing to resolve it is to use "null" instead of an empty String.
meaning: mDeptView.setWhereClauseParam(1, null);

This will solve the issue, without having a functional decrease!

Having questions? Feedback me on this entry Clemens Utschig

Tuesday, April 13, 2004

Object identity and usage of Object.equals()

Today while reading through a filed bug, i started searching little on google for a good paper describing the difference and usage of comparing identities of objects / and comparing just the nested values ..

.. and what wonder I found a pretty good paper written by stephen davies on this issue, so for thoswe of you, who are interested, or just not to fimilar with this issue, get some time and read through it ..


Having questions? Feedback me on this entry Clemens Utschig

iAS/OC4J 903: Creating your own custom login-module

Ever needed to connect to different "data"sources for login, then provided in the standard distribution of iAS/OC4J?

Well, if you have to do this, it's pretty easy and probably something around a day of work ... :)

All starts with creating your own CustomLoginModuleClass and implementing the javax.security.auth.spi.LoginModule - which is the base interface for a (your custom) loginModule.

Having this interface implemented, and your own logic there to validate users against whatever, you're just some more steps beyond having it working ... :)

The first is the deployment of your new loginModule class. Basically you have two choices here, putting it (including all the necessary libs you have used) into the %JAVA_HOME/jdk/jre/lib/ext of the jdk that is used as runtime for your container, or the second way (which is from my point of view the very better way), extract manifest.mf from oc4j.jar and add your jar to the classpath in there.

The very last thing to do is adding your new LoginConfiguration, including the loginModule class into jazn-data.xml, from the home container (%OC4J_HOME/j2ee/home) and voila, you should be able to call it out of your application by using a loginContext.

Having questions? Feedback me on this entry Clemens Utschig

Sunday, April 11, 2004

JHeadstart - J2EE RAD by generation

Our consulting folks from Netherlands started pretty long time ago building a nice, cool framework that let's you rapidly generate J2EE applications based on BC4J/Toplink, Struts or Oracle MVC Framework and as frontend jsp*s or uix pages and integrates slightly into our JDeveloper IDE.

As I worked with one of the last versions, that let me generate JSPs, as we needed them to fullfill the customer requirements, I started digging little into it - and liked it very much - as it really gave me the chance to generate most of my prototype app, and this within some hours - so if you have the time and are interested, give JHeadstart a try!


Having questions? Feedback me on this entry Clemens Utschig

Sun releases Java Studio Creator, anyone out there, who already played with it?!

Just back from my - bad weather - sailing trip, i went to the Java - Homepage and saw the following ..

Java Studio Creator:
An IDE to Create Web Applications Read about Sun Java Studio Creator, the IDE that enables you to create two-tier Web applications. In addition, this easy-to-use tool simplifies and streamlines access to databases and web services from behind dynamic HTML user interfaces as easy as drag-and-drop.

Is there anyone out there, who already played little around with it? if yes, feedback would be very appreciated ..

Having questions? Feedback me on this entry Clemens Utschig

Friday, April 02, 2004

SAILING: one week, 50 feet @ adriatic sea :)

Yes, I can't believe it - just another day, and i will be @ one of my greatest hobbies - sailing, on a great boat, with some friends around - for a week, cruising through the adriatic sea.
With hopefully something around 4-6 Bft*s, to have some real fun there ...

For all of you knowing about sailing; It's a First 47.7 - with probably everything to imagine, including a huge Spi.

Depending on my mobile access, and even more depending - if i get my palm to work again (including the browser), I will maybe blog around from the boat :) - otherwise I'll do so when I'm back ...

Anyway wishing all my readers a nice Easter-week (end).

Having questions? Feedback me on this entry Clemens Utschig

BC4J 9034: Paging after passivation of ExpertMode, readonly VO*s with applied ViewCriterias

Yesterday evening, while (still) debugging into the JDK1.4 issue, one of the guys here - came up with an interesting issue - and i just want to share the outcome of our findings here ..

Imagine having a VO that is expertMode, and NOT EO-based, which will per default not passivated.

So after turning this one, bear in mind, that when you apply ViewCriteria*s to it (VO.applyViewCriteria ..) - these settings will be passivated (and activated) too..

So after paging through the pages of my VO (and not passivating after each JSP) - everything worked cool,
until the first time, where i started passivation in between the paging process, because of showing up a popUp (with details of a row) - and forced our bc4j framework to release my DB-Connection before doing so.
When switching back to the jsp - that included my paging, suddenly my VO seemed to be empty (VO.getRowCount == 0, while VO.getEstimatedRowCount still returned the correct number of filtered rows).

So after thinking little on it, i personally got the idea that when reactivating from the snapshot (as we just save the delta to the snap) - we should re-execute our query (just in the action, after paging to the next page) - by using VO.executeQuery(); -> and voila it worked :) - as we create a new SessionCookie for our user, after getting back from a detail, i consider this as default behaviour - as we get to a new, 'clean', enviroment ..

hint: to check if you have ViewCriteria*s applied just use VO.getViewCriteriaClause().

If i have some spare-time (probably when flying back home :) today), i will try to build a little testcase for that, to ensure that we're on the best way here ..

Having questions? Feedback me on this entry Clemens Utschig

Thursday, April 01, 2004

Dynamic invocation of classes- what a cool thing

As in one of my posts already mentioned, i get more and more fascinated by the java.lang.reflect API and it's enormous power!

When designing solutions, that a entirely component based, and focused on exchangebility of the underlying components - it can be a really great help for defining the interfaces / and relations outside the application ..

One thing i came through was when using helper / Service to worker pattern - wouldn't it be cool having the location of my service defined through jndi / or a file - and there to specify what class to use? Something that can be easily done with reflection - so if you're interested - just click yourself to the source of java-tech and search for reflection.

Having questions? Feedback me on this entry Clemens Utschig

JDK1.4 Drivers & OCI in BC4J - not that huge miracle :-)

Just as a little follow up on one of my posts, 'couple days ago;
Today I added some stuff, while i was debugging into a bc4j issue - with the Jdk1.4 drivers:


On friday afternoon, a nice thing poped up at a customer -BC4J, with OCI,
Basicly ct. want's to use OCI as db-driver instead of thin, and all that together with Jdk1.4. in Jdeveloper and iAS 903.
On otn there's a nice 'how-to' what you have to do.. and how to setup the stuff in a standalone java-app. Here are some additional infos, getting it to work ...
.
So everything starts with downloading the correct drivers from OTN (meaning the jars, and dll*s / so*s), and ensure that your oracle-client is working properly, .. then the fun really starts :)
(btw. as it's always best to use the dll*s, so*s and jars from the db distribution, the easiest way getting them is connecting to your DB-Server and copying ojdbc14.jar from /jdbc/lib and the dll*s from /bin directory of your DB.home)

Look for the dll*s / so*s in your $ORACLE_HOME/bin directory, if they are not there - download them into here, and the jar files into your lib-home.
.
When using jdev, ensure that you have correctly set $ORACLE_HOME (to the home of your ORACLE_CLient install) and that your path includes $ORACLE_HOME/bin - best, at the very first beginning ..
Secondly ensure that you extracted the driver-files to a new directory, and reference just the new ones (with a new lib) from your JDev -project;
Do not overwrite the old jar*s (named classes12.jar, classes12_dms.jar) in the $JDEV_HOME/jdbc/lib dir.
otherwise you will damage jdev - meaning you're not able to test your DB-connections, from the connections-tab any more, or browse through the data, on the other hand it's the only idea to ensure when you're testing with the new drivers, the old ones are not in the classpath :(

Afterwards just start jdeveloper from the shelll where you set all the env var*s, edit your connection from thin to oci - and voila it's working... :)

Having questions? Feedback me on this entry Clemens Utschig

JDev 10g - It's all about ADF & great new features

As some of you already play around with JDev 10g - and i got some feedback around this, just something to bear in mind - by now the donloadable version on OTN is NOT "product " supported , which means that you won't get official support through filing a metalink tar, just within the metalink forums (where our pm*s are usually on :) ) - but anyway as soon as it's official released, i will try to keep my focus on stuff there too ..
Wan't some pre-info? Then check out mike's and steve's blog :)

Having questions? Feedback me on this entry Clemens Utschig

JDK 1.3 - fast quick and dirty object logging? An example ..

When developing an application -
even more when you just develop some parts of it- for me when having other people testing, it's always interesting - what information they fill into the objects they pass along to the methods ..
This becomes even more relevant - if the applications that are using your methods (webservices ...), are tested and developed by a 3rd party.

So during one of my flights a built up a quick example .. for an object-logger, with using java.lang.reflect. package - as I got really fascinated by this runtime-API :) and JDK1.3 doesn't support the XMLEncode ( decode package, that came along with 1.4 ..

The following code is just intended - as an example, of the usage of reflection, but why not using some funnny techs/api*s for such things too?!

package log;

 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;

 import java.util.logging.*;

/**
 * Fast and simple ObjectLogger that prints out the values of
 * public fields and executes all <b>public</b>
 * getXXX methods.
 * This is done by usage of java.lang.reflection API
 * @author Clemens Utschig - Utschig
 * @version 1.0
 * @date   23.03.2004
 */
public class ObjectLogger  {

  /**
   * The apache Logger
   */
  private static Logger mLogger;

  /**
   * GoF Singleton Instance, excutes one time the
   * private constructor
   *
  private static ObjectLogger mObjectLogger = new ObjectLogger();

  /**
   * GoF Singleton - therfor private Constructor - excuted only once,
   * just initalized the logger
   */
  private ObjectLogger() {
   mLogger = Logger.getLogger("ObjectLogger");
  }

  /**
   * Returns the singleton - instance, created as by the
   * member var.
   * @return the instance of the ObjectLogger
   */
  public static ObjectLogger getInstance () {
   return mObjectLogger;
  }

  /**
   * Logs the public fields of a given
   * Object !
   * @param pObject the Object to log
   */
  public static void logObject (Object pObject) {
   if (pObject != null) {
    mLogger.info(" --------- start logging Object ----------");
    mLogger.info("ClassName: " + pObject.getClass().getName());

    // get the publid fields with reflection
    Field [] objectFields = pObject.getClass().getFields();
    if ((objectFields != null) && (objectFields.length > 0)) {
      mLogger.info(" --------- public members ----------");
      for (int fieldIndex = 0; fieldIndex < objectFields.length; fieldIndex++) {
        try {
           mLogger.info(" - Name [" +objectFields[fieldIndex].getName()+ "] " +
                       " type [" +objectFields[fieldIndex].getType()+ "] " +
                      " value [" +objectFields[fieldIndex].get(pObject)+ "] ");
        } catch (IllegalAccessException illegalAccessExc) {
          mLogger.info("IllegalArgumentException");
        }
      }
    }

    // get the pulic methods
    Method [] objectMethods = pObject.getClass().getMethods();
    if ((objectMethods != null) && (objectMethods.length > 0)) {
      mLogger.info(" --------- Invocation of methods ----------");
      for (int objectMethodIndex = 0; objectMethodIndex < objectMethods.length; objectMethodIndex++) {
        try {
          if ((objectMethods[objectMethodIndex].getParameterTypes().length == 0) &&
              (objectMethods[objectMethodIndex].getName().startsWith("get"))){
            mLogger.info(" - MethodName [" + objectMethods[objectMethodIndex].getName()+ "] " +
                              " type ["  + objectMethods[objectMethodIndex].getReturnType().getName() + "]" +
                              " value [" + objectMethods[objectMethodIndex].invoke(pObject, new Object [] {}) + "] ");
          }  
        } catch (InvocationTargetException invocationTargetExc) {
          // do nothing
        } catch (IllegalAccessException illegalAccessExc) {
          // do nothing
        } catch (Exception allOthers) {
          // do nothing too
        }
      }
    }

     mLogger.info(" --------- End logging Object ----------");
   } else {
     mLogger.warning("Object given is NULL !");
   }
    
  }

  /**
   * Logs the public fields/methods of a given Object Array !
   * @param pObject[] the ObjectArray to log
   */
  public static void logObject (Object pObject []) {
    if (pObject != null) {
      mLogger.info(" -- start logging ObjectArray, size: " + pObject.length + " --");
      for (int objectIndex = 0; objectIndex < pObject.length;  objectIndex++) {
        logObject(pObject[objectIndex]);
      }
      mLogger.info(" -- end logging ObjectArray --" );
    } else {
      mLogger.warning("ObjectArray given is null !");
    }
  }