Friday Dec 07, 2012

Selective Suppression of Log Messages

Those of you who regularly read this blog will probably have noticed that I have a strange predilection for logging related topics, so why break this habit I ask? 

Anyway here's an issue which came up recently that I thought was a good one to mention in a brief post.  The scenario really applies to production applications where you are seeing entries in the log files which are harmless, you know why they are there and are happy to ignore them, but at the same time you either can't or don't want to risk changing the deployed code to "fix" it to remove the underlying cause. (I'm not judging here). The good news is that the logging mechanism provides a filtering capability which can be applied to a particular logger to selectively "let a message through" or suppress it. This is the technique outlined below.

First Create Your Filter 

You create a logging filter by implementing the java.util.logging.Filter interface. This is a very simple interface and basically defines one method isLoggable() which simply has to return a boolean value. A return of false will suppress that particular log message and not pass it onto the handler.

The method is passed the log record of type java.util.logging.LogRecord which provides you with access to everything you need to decide if you want to let this log message pass through or not, for example  getLoggerName(), getMessage() and so on.

So an example implementation might look like this if we wanted to filter out all the log messages that start with the string "DEBUG" when the logging level is not set to FINEST:

 public class MyLoggingFilter implements Filter {
    public boolean isLoggable(LogRecord record) {
        if (  !record.getLevel().equals(Level.FINEST) 
            && record.getMessage().startsWith("DEBUG")){
         return false;   
        return true;


This code needs to be put into a JAR and added to your WebLogic classpath.  It's too late to load it as part of an application, so instead you need to put the JAR file into the WebLogic classpath using a mechanism such as the PRE_CLASSPATH setting in your domain setDomainEnv script. Then restart WLS of course.


The final piece if to actually assign the filter.  The simplest way to do this is to add the filter attribute to the logger definition in the logging.xml file. For example, you may choose to define a logger for a specific class that is raising these messages and only apply the filter in that case. 

<logger name="some.vendor.adf.ClassICantChange"

You can also apply the filter using WLST if you want a more script-y solution.

Thursday Apr 05, 2012

Application Scope v's Static - Not Quite the same

An interesting question came up today which, innocent as it sounded, needed a second or two to consider. What's the difference between storing say a Map of reference information as a Static as opposed to storing the same map as an application scoped variable in JSF? 

From the perspective of the web application itself there seems to be no functional difference, in both cases, the information is confined to the current JVM and potentially visible to your app code (note that Application Scope is not magically propagated across a cluster, you would need a separate instance on each VM).

To my mind the primary consideration here is a matter of leakage. A static will be (potentially) visible to everything running within the same VM (OK this depends on which class-loader was used but let's keep this simple), and this includes your model code and indeed other web applications running in the same container. An Application Scoped object, in JSF terms, is much more ring-fenced and is only visible to the Web app itself, not other web apps running on the same server and not directly to the business model layer if that is running in the same VM.

So given that I'm a big fan of coding applications to say what I mean, then using Application Scope appeals because it explicitly states how I expect the data to be used and a provides a more explicit statement about visibility and indeed dependency as I'd generally explicitly inject it where it is needed. 

Alternative viewpoints / thoughts are, as ever, welcomed...

Thursday Feb 02, 2012

Oracle XE and Hudson Co-Existence

A small roadblock that hit me this morning that is worth documenting if only for my own reference.  I run my main Hudson install on my Linux server somewhere in the wilds(?) of Texas, however, I wanted to check something out with Hudson as a Windows service, something which I've not done for a few months.  

Starting Hudson with java -jar hudson-2.2.0.war however failed with a port bind error. It seems that port 8080 was in use.  I was a bit confused because I didn't have an Apache, Tomcat or OC4J running at that address, something else, something new, had grabbed the port.  Fortunately, as ever, I had TCPview installed and that quickly showed me that the owning process was the TNS Listener process from my newly installed Oracle XE 11g edition. 

Now I could have simply booted Hudson on a different port using the --httpPort argument, however, the chances are that I will be wanted to start other stuff on 8080 as well so XE had to be kicked off of that port for it's HTTP listener. This is done quickly, and without any re-starting, from SQLPlus:

Enter user-name: system
Enter password:
Connected to:
Oracle Database 11g Express Edition Release - Production
SQL> begin
  2  dbms_xdb.sethttpport('8282');
  3  end;
  4  /
PL/SQL procedure successfully completed.
SQL> exit
Disconnected from Oracle Database 11g Express Edition Release - Production

Short and sweet, Oracle now sits on 8282 and 8080 is free for Hudson. 

Friday Jan 06, 2012


Further to my earlier article on using the weblogic.appc command to precompile the pages in ADF applications the question came up about how to automate the same thing from Ant. 

Now in principle this should be pretty simple as the same appc command is available as an Ant task.  However, the documentation is not particularly illuminating and completely lacks any examples so you can fumble around for hours if you're a skim reader and don't pay really close attention. 

Anyway an example is worth a 1000 words. Here's the same example as last time but in Ant form.  You will still need to follow the same process for digging out the libraries that you require.


<project name="AppcTest" default="precompile" basedir=".">
  <description>Sample build file using Ant to call WLS APPC</description>

  <property name="wls_root" value="C:/builds/WLS_PS4" />
  <property name="wls_home" value="${wls_root}/wlserver_10.3" />
  <property name="adf_lib_root" value="${wls_root}/oracle_common/modules"/>
  <property name="common_lib_root" value="${wls_home}/common/deployable-libraries"/>  

  <path id="wls.classpath">
    <fileset dir="${wls_home}/server/lib">
      <include name="*.jar"/>

  <taskdef name="wlappc" classpathref="wls.classpath" 

  <target name="precompile" description="Calls WLS APPC to pre-compile an EAR">
    <wlappc source="myapp.ear" 
            classpath="${adf_lib_root}/oracle.adf.share_11.1.1/adfsharembean.jar" >
      <library file="${adf_lib_root}/oracle.adf.view_11.1.1/"/>
      <library file="${adf_lib_root}/oracle.adf.model_11.1.1/"/>
      <library file="${common_lib_root}/jstl-1.2.war"/>
      <library file="${common_lib_root}/jsf-1.2.war"/>


Friday May 06, 2011

New Oracle Author Podcast

Just published, is my recent interview with a well known face in the ADF community and OTN ACE Director, Sten Vesterli of the aptly named Scott/Tiger. Sten's been busy working away on his second book Oracle ADF Enterprise Application Development  - Made Simple. So the podcast is available now on OTN - download and listen.

Hawaii, Yes! Duncan has been around Oracle technology way too long but occasionally has interesting things to say. He works in the Development Tools Division at Oracle, but you guessed that right? In his spare time he contributes to the Hudson CI Server Project at Eclipse
Follow DuncanMills on Twitter

Note that comments on this blog are moderated so (1) There may be a delay before it gets published (2) I reserve the right to ignore silly questions and comment spam is not tolerated - it gets deleted so don't even bother, we all have better things to do with our lives.
However, don't be put off, I want to hear what you have to say!


« July 2016