You are here: Home » Blog

Implicit default constructors

Posted on Tuesday, December 09 2014 at 08:24 | Category: Java | 0 Comment(s)

As you certainly know, if there is no constructor implemented in a class, the compiler implicitly synthesizes a default constructor. Hence, the following code compiles:

public class ClassA {

    public static void main(String[] args) {
        new ClassA();
    }
}

The disassembled code shows that there is indeed a constructor which essentially calls its super constructor, java.lang.Object.<init>:

$ javap -c ClassA.class
Compiled from "ClassA.java"
public class ClassA {
public ClassA();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #1                  // class ClassA
       3: invokespecial #16                 // Method "<init>":()V
       6: return
}

Now, there is one detail which even long-time Java developers are not always aware of: if any other constructor overload is added to the class, the compiler will not synthesize a default constructor - hence, the following code does not compile:

public class ClassA {

    public ClassA(int a) { }

    public static void main(String[] args) {
        new ClassA();
    }
}
ClassA.java:7: error: constructor ClassA in class ClassA cannot be applied to given types;
        new ClassA();
        ^
  required: int
  found: no arguments
  reason: actual and formal argument lists differ in length
1 error

This is in accordance to the Java Language Specification: 8.8.9. Default Constructor where it says:

If a class contains no constructor declarations, then a default constructor is implicitly declared.
...

Means, if there are any constructor declarations, then no default constructor will be created by the compiler. Note that there is also the same behavior in C++. Note also that the term "default constructor" as it is used by the language specification only refers to the parameterless constructor created by the compiler - hence, strictly spoken, a parameterless constructor which is explicitly implemented in the class is not a default constructor (even though developers often call it like that).

Normally, this is not an issue, since the compiler will emit the above error when we try to instantiate the class through the default constructor. However, if the object is created dynamically (e.g. through reflection), there will be no compile time error - it will become a runtime error then:

public class ClassA {

    public ClassA(int a) { }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class clazz = Class.forName("ClassA");
        ClassA obj = (ClassA) clazz.newInstance();
    }
}
Exception in thread "main" java.lang.InstantiationException: ClassA
	at java.lang.Class.newInstance(Unknown Source)
	at ClassA.main(ClassA.java:9)
Caused by: java.lang.NoSuchMethodException: ClassA.<init>()
	at java.lang.Class.getConstructor0(Unknown Source)
	... 2 more
</init>

This can be important when using persistence frameworks which do these kind of things in the background. Other examples are dependency injection frameworks which might complain at the lack of default or empty constructor, if no constructor has the @Inject annotation.


Tracking Application Module Pool operations

Posted on Thursday, November 20 2014 at 06:53 | Category: Oracle ADF & JDeveloper | 0 Comment(s)

To get a better understanding how the Application Module Pool works in Oracle ADF, it can be useful to log some of its methods as they are called. This can also be useful to track down Application Module Pool related issues, or even to collect usage and performance statistics.

The entry point for such a logging facility is to define a custom Application Module Pool class. Note that this is not something you would or should do in the final application - it is usually not necessary, but can be convenient for the use cases mentioned above. The class to instantiate as the Application Module Pool is defined through the PoolClassName property on the Application Module's configuration:

The configuration is stored in the bc4j.xml configuration file, and we could also set the property by simply editing this file:


  <appmoduleconfig deployplatform="LOCAL" jdbcname="ApplicationDB" jbo.project="model.Model" name="AppModuleLocal" applicationname="model.AppModule">
     <am-pooling poolclassname="test.CustomApplicationModulePool">
     <database jbo.locking.mode="optimistic">
     <security appmodulejndiname="model.AppModule">
  </security></database></am-pooling></appmoduleconfig>

Now, the ADF runtime will instantiate an object of the defined class as the Application Module's pool. We simply need to implement this class, inheriting from ApplicationPoolImpl:


package test;

import java.util.Properties;
import oracle.jbo.ApplicationModule;
import oracle.jbo.common.ampool.ApplicationPoolImpl;
import oracle.jbo.common.ampool.SessionCookie;

public class CustomApplicationModulePool extends ApplicationPoolImpl {
    public CustomApplicationModulePool() {
        super();
    }

    ...

}

By overriding the methods which are of interest, we can add logging to the application module pool and for example track how Application Modules are checked out and released. Ideally a logging API such as java.util.logging should be used - for simplicity, I am using System.err in the examples. The most interesting methods to track Application Module usage are useApplicationModule() which is called by the framework to check out an application module from the pool, releaseApplicationModule() which is called to give back an application module to the pool and probably createSessionCookie() which creates a session cookie for a BC4J session:


    @Override
    public SessionCookie createSessionCookie(String applicationId,
                                             String sessionId,
                                             Properties properties) {
        System.err.printf("createSessionCookie(applicationId=%s, sessionId=%s, properties=%s)\n",
                           applicationId, sessionId, properties);

        SessionCookie result = super.createSessionCookie(applicationId, sessionId, properties);

        System.err.printf("    Result: %s\n", result.getSessionId());

        return result;
    }


    @Override
    public ApplicationModule useApplicationModule(final SessionCookie cookie,
                                                  final boolean checkout) {
        System.err.printf("useApplicationModule(session id=%s, checkout=%s)\n", 
                          cookie.getSessionId(), checkout);

        ApplicationModule result = super.useApplicationModule(cookie, checkout);

        System.err.printf("    Result: %s\n", System.identityHashCode(result));

        return result;
    }

    @Override
    public void releaseApplicationModule(SessionCookie cookie,
                                         boolean manageState) {
        System.err.printf("releaseApplicationModule(cookie=%s, manageState=%s)\n",
                          cookie, manageState);

        super.releaseApplicationModule(cookie, manageState);
    }

    @Override
    public void releaseApplicationModule(SessionCookie cookie,
                                         int releaseFlags) {
        System.err.printf("releaseApplicationModule(cookie=%s, releaseFlags=%s)\n",
                          cookie, releaseFlags);

        super.releaseApplicationModule(cookie, releaseFlags);
    }

We can now observe how and when the ADF runtime retrieves Application Modules form the pool. Remember that each HTTP request which requires BC4J will result in an Application Module checkout and a corresponding release before the request finishes. Also remember that each Application Module has its own database transaction (unless it is a nested Application Module, in which case it inherits the transaction from its parent). Hence, logging information about the associated database transaction can also be useful.


Using Lambdas to implement a function table

Posted on Monday, November 17 2014 at 08:28 | Category: Java | 0 Comment(s)

When I implemented an expression parser for arithmetic expressions (such as t*x+sin(x-5) + π), one part was to create a symbol table to look up constant values such as π, variables such as x and t, but also functions like sin(x). My initial approach had this structure:

 

This allowed me to create a symbol table as a HashMap, and then to add variables, constants or functions into the table:


private Map<String, Symbol> table = new HashMap<>();
...
table.put("sin",  new SinFunction());
table.put("log",  new LogFunction());
...

This works well, but requires a whole new class for each new function, where each of the classes simply provides a getValue() method which delegates to the corresponding static method from Math:

public double getValue(double arg) {
   return Math.sin(arg);
}

Using lambda expressions, the class structure can be much simplified:

Instead of an abstract class Function with specific sub classes which implement the getValue() method, we provide a concrete Function class which delegates to the functional interface DoubleFunction. The instantiation of the Function objects can then be moved into the SymbolTable class, essentially as a convenient method:


public void putSymbol(String name, DoubleFunction<Double> fun) {
   table.put(name, new Function(name, fun));
}

Now, adding new function to the symbol table is straight forward, using a lambda expression:

symbolTable.putSymbol("sin", x -> Math.sin(x));
symbolTable.putSymbol("log", x -> Math.log(x));

Especially we do not need to add another class when adding a new function. The class structure of the symbol table remains stable, all we need is to register the new function through a call to SymbolTable.putSymbol().

Besides simply mapping a function name to a method from the Math class, this works equally well for any user defined function, for example:

symbolTable.putSymbol("f1", x -> x*x + 42*x + 19);
symbolTable.putSymbol("f2", x -> Math.cos(x*x) + 42*x);

Since the Function class holds a reference to the lambda expression through the DoubleFunction interface, we simply call the DoubleFunction.apply() method to evaluate the function for a given x value:

public class Function extends Symbol {

   private DoubleFunction<Double> theFunc;

   ...

   @Override
   public double getValue(double x) {
      return theFunc.apply(x);
   }
}

Enabling global breakpoints in JDeveloper

Posted on Friday, November 07 2014 at 10:21 | Category: Oracle ADF & JDeveloper | 0 Comment(s)

In larger ADF projects with more than one workspace and with many projects, it might happen that a breakpoint can not be set on a class from a different workspace or project, even though JDeveloper properly navigates to the source file.

In this case, make sure that the "Scope for New Breakpoints" is set to "Global" in the "Debugger/Breakpoints" preferences (open the preferences dialog through "Tools/Preferences"):

 


Displaying results 21 to 24 out of 115