Friday, July 29, 2011

ADF BC Service Interface Deployment slowly so I dont forget

Foolproof way to get this stuff deploying for OUR enviroment:

Model Project
  • Right click --> Project Properties
  • Deployment
  • Remove all old deployments
  • Create new Deployment (New Button)
  • Select Business Component Service Interface from the drop down
  • Enter Deployment Profile Name: ModelDeploy
  • Click ok
  • Edit each project and in the JAR Options select Compress Archive
  • When editing the EJB Module in File Groups > Project Outputs > Filters select all tick boxes from model folder down in tree.
  • Save All


EAR
  • Right click --> Application Properties
  • Deployment [Project Name]Deploy
  • Select Application Assembly
  • Tick all

Java 7

So Java 7 was released yesterday. Here are a few things I found interesting taken from the release guide. Some very nice features that I have been waiting for for a long time - my favorites are the Stings in switch and catching multiple exceptions but that is just me. For the full story http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html or  http://download.oracle.com/javase/7/docs/

Language
  • Binary Literals - 0b or 0B. 
    • Ok but I wont be using it so much.
  • Underscores in Numeric Literals - Any number of underscore characters (_) can appear anywhere between digits in a numerical literal.
    • This may be quite confusing for my brain 52 == 5___2 weird but I suppose it helps with grouping
  • Strings in switch Statements - You can use the String class in the expression of a switch statement.
    • FINALLY been waiting for this.
  • Type Inference for Generic Instance Creation - You can replace the type arguments required to invoke the constructor of a generic class with an empty set of type parameters (<>) as long as the compiler can infer the type arguments from the context.
    • Bit hard to read but I will get used to it.
  • Improved Compiler Warnings and Errors - The Java complier generates a warning at the declaration site of a varargs method or constructor with a non-reifiable varargs formal parameter. Java SE 7 introduces the compiler option -Xlint:varargs and the annotations @SafeVarargs and @SuppressWarnings({"unchecked", "varargs"}) to supress these warnings.
  • The try-with-resources Statement - A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. java.lang.AutoCloseable, java.io.Closeable interface can be used as a resource. The classes java.io.InputStream, OutputStream, Reader, Writer, java.sql.Connection, Statement, and ResultSet have been retrofitted to implement the AutoCloseable interface and can all be used as resources in a try-with-resources statement.
  • Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking - A single catch block can handle more than one type of exception. 
    • Nice this will help a lot with repeated code bloat. 
NIO
More comprehensive support for accessing file system.


Swing
Create Translucent and Shaped Windows 


Concurrency
The fork/join framework, which is based on the ForkJoinPool class, is an implementation of the Executor interface. It is designed to efficiently run a large number of tasks using a pool of worker threads. A work-stealing technique is used to keep all the worker threads busy, to take full advantage of multiple processors.

Networking
URLClassLoader.close
This method effectively eliminates the problem of how to support updated implementations of the classes and resources loaded from a particular codebase, and in particular from JAR files.

JDBC
  • try-with-resources automatically close resources : Connection, ResultSet, Statement
  • RowSet 1.1: The introduction of the RowSetFactory interface and the RowSetProvider class, which enable you to create all types of row sets supported by your JDBC driver.
VM
Garbage-First Collector replaces the Concurrent Mark-Sweep Collector - targeted for multi-processors with large memories,.
Java HotSpot Virtual Machine Performance Enhancements

Friday, July 22, 2011

*** NOT ADF - Glassfish custom login module

Step 1) Write your custom module - there are enough examples out there - I used (http://x-techteam.blogspot.com/2008/03/glassfish-login-module-simple-example.html)
Step 2) Add to login.conf [glassfish location]\glassfish\domains\[domain name]\config
yourRealm{
    za.co.jaas.realm.YourLoginModule required;
};

Step 3) Admin console setup
  • Goto admin console : http://localhost:4848 and Login
  • Goto Cconfigurations\[Your config]\Security\Realms
  • Click new button
  • ClassName: za.co.jaas.realm.YourRealm (choose second custom radio button)
  • Name:     yourRealm
  • Press the ok button
BIG BIG NOTE: (Save yourself hours of time)
Tick Default Principal To Role Mapping in configurations\[Your config]\Security\ and save
stop glassfish
REDEPLOY APPLICATION
start glasfish

NOTE : When writing a startup script please remeber to start db before start of Assfish otherwise you will have some strange funky errors.

Thursday, July 21, 2011

ADF manual LOV binding backing bean selected value

Ok so I tried this a whole bunch of ways and this is the way I will follow from now on to save my self MUCH hassle.

What I want is a VO based SelectOneItem that has an empty selected item which is selected by default. Also the value of the SelectItem must be custom and NOT index based.


  • The Backing Bean

  private String selectedCode = null;
  public String getSelectedCode() {     return selectedCode;   }   public void setSelectedCode(String selectedCode) {     this.selectedCode = selectedCode;   }

  • The jspx page
          
  <af:selectOneChoice value="#{viewScope.yourBean.selectedCode}"     label="#{viewBundle.JSPXNAME_LBL_YOURLABEL}"     required="#{bindings.YourLovCode.hints.mandatory}"     shortDesc="#{bindings.YourLovCode.hints.tooltip}" id="soc4"     styleClass="colspec_medium" unselectedLabel="" valuePassThru="true">
      <af:forEach items="#{bindings.YourLOVIterator.allRowsInRange}" var="item">
        <f:selectItem id="si3" itemLabel="#{item.attributeValues[1]}" itemValue="#{item.attributeValues[0]}"/>       </af:forEach>                  
  </af:selectOneChoice>

Wednesday, July 20, 2011

ADF bind variables : Note to self + groovy

Backing Bean:
ADFContext.getCurrent().getSessionScope().put("groovyBaby", "11111");

Groovy Bind Variable Expression
adf.context.sessionScope.groovyBaby

Make sure the value is of the correct data type.

Adding an ADF LOV to the aether

1) Create the View Object

  • This is done as you would create any VO and add the VO to the application module. Dont forget to refresh Data Controls section.


2) Bind LOV on page defs (Executable section)

  • Navigate to the page you want to add the LOV to
  • Click on the bindings tab.
  • Click the green plus button on the Executables section
  • Select iterator
  • Press ok
  • Select your newly created VO
  • Press OK
  
3) Add a List to bindings
  • Press the green plus button on the Bindings Section
  • Select list then ok
  • Standalone select one value list then ok
  •  Select your Iterator from the base data source list
  • Select your display attribute

4) Create SelectItem on page
  •   Add the following tag to your page REMEMBER that LovCode must be replaced by your newly create binding
                  <af:selectOneChoice value="#{bindings.LovCode.inputValue}" label="#{viewBundle.COMMISSION_LBL_COMMISSIONTYPE}"
                                      required="#{bindings.LovCode.hints.mandatory}"
                                      shortDesc="#{bindings.LovCode.hints.tooltip}" id="soc4"
                                      styleClass="colspec_medium">
                    <f:selectItems value="#{bindings.LovCode.items}" id="si4"/>                  </af:selectOneChoice>

Monday, July 18, 2011

Classpath problem with Service interface class

When testing functionality on a newly service enabled Application module custom class I got a class not found exception.

My jars on my model project where not set to be deployed by default on deployment. This was working because the jars where deployed by default on the war.

Sunday, July 17, 2011

Error Handling ADF

Created a custom error handler to customize any exceptions that come along. (We throw message keys from the model layer and handle them auto-magically in the handler).

Create an exception handler class.

Add the attribute ErrorHandlerClass  to the root Application tag to DataBindings.cpx ErrorHandlerClass="za.co.transcode.adf.mdm.model.messages.ReferenceCustomMessageHandler".

NOTE: This is not production ready code and needs a few performance tweaks but you will get the idea. This is in our common project you would just override this class in the dependant projects with skipLists and overrideList populated (skipList = {{"java.lang.NullPointerException", null}, {"java.sql.SQLException", "1234"}} OR overrideList = {{"java.lang.SQLException", "9999", "This should never happen"}} )

Code for custom handler:

package za.co.transcode.adf.common.model.messages;

import java.sql.SQLException;

import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCErrorHandlerImpl;

import oracle.jbo.JboException;

import za.co.transcode.adf.common.exception.MessageBaseException;
import za.co.transcode.adf.common.util.MessageBundleUtil;


public class CustomMessageHandler extends DCErrorHandlerImpl {
  private String[][] skipList = null;
  private String[][] overrideList = null;

  public CustomMessageHandler() {
    this(true);
  }
  public CustomMessageHandler(boolean setToThrow) {
    super(setToThrow);
  }

  public CustomMessageHandler(String[][] skipList, String[][] overrideList) {
    this(true, skipList, overrideList);
  }

  public CustomMessageHandler(boolean setToThrow, String[][] skipList, String[][] overrideList) {
    this(setToThrow);
    this.setSkipList(skipList);
    this.setOverrideList(overrideList);
  }

  public String getDisplayMessage(BindingContext context, Exception exception) {

    if(isInSkipList(exception)) {
      return null;
    }

    String overrideMessage = overrideMessage(exception);
    if(overrideMessage != null) {
      return overrideMessage;
    }

    String message = super.getDisplayMessage(context, exception);
    return message;
  }

  private boolean isInSkipList(Exception exception) {
    if(getSkipList() != null) {
      for(String[] skip : getSkipList()) {
        if(skip != null && skip.length == 2) {
          String className = skip[0];
          String itemCode = skip[1];

          if(matchClass(exception.getClass(), className) && matchItem(exception, itemCode)) {
            return true;
          }
        }
      }
    }
    return false;
  }

  private String overrideMessage(Exception exception) {
    if(exception instanceof MessageBaseException) {
      return MessageBundleUtil.getMessage(getMessageBundle(), exception.getMessage(),
          ((MessageBaseException) exception).getProperties());

    }
    if(getOverrideList() != null) {
      for(String[] override : getOverrideList()) {
        if(override != null && override.length == 3) {
          String className = override[0];
          String itemCode = override[1];
          String message = override[2];

          if(matchClass(exception.getClass(), className) && matchItem(exception, itemCode)) {
            if(exception instanceof SQLException) {
              message = MessageBundleUtil.formatMessage(message, ((SQLException) exception).getErrorCode());
            }

            return message;
          }
        }
      }
    }
    return null;
  }

  private boolean matchClass(Class exceptionClass, String className) {
    if(className == null) {
      return true;
    }

    try {
      Class clazz = Class.forName(className);
      if(clazz.isAssignableFrom(exceptionClass)) {
        return true;
      }
    } catch(Throwable t) {
      return false;
    }
    return false;
  }

  private boolean matchItem(Exception exception, String overrideCode) {
    if(overrideCode == null) {
      return true;
    }

    try {
      if(exception instanceof SQLException) {
        SQLException sqlException = (SQLException) exception;
        if(String.valueOf(sqlException.getErrorCode()).equalsIgnoreCase(overrideCode)) {
          return true;
        }
      }

      if(exception.getMessage() != null && exception.getMessage().matches(overrideCode)) {
        return true;
      }
    } catch(Throwable t) {
      return false;
    }
    return false;
  }

  protected String[][] getSkipList() {
    return skipList;
  }

  protected void setSkipList(String[][] skipList) {
    this.skipList = skipList;
  }

  protected String[][] getOverrideList() {
    return overrideList;
  }

  protected void setOverrideList(String[][] overrideList) {
    this.overrideList = overrideList;
  }

  protected String getMessageBundle() {
    return MessageBundleUtil.DEFAULT_BUNDLE_NAME;
  }
}


NOTE: when using OperationBindings from the view layer when your method throws and exception the method is stopped as you would expect but your execpetion is  then swallowed by ADF Error handling - so it is your responsibility to check the operations error messages post execute.

Monday, July 11, 2011

Dependant ADF Libraries import - Application Module not found refactoring

Open Model.jpx (should be in the model package).


Select the Imports menu item on the left hand side.

Click the green plus button.
Find and select the jar you wish to work with.

Job done.

You can now included an linked AM files as nested.