Tuesday, December 29, 2009

EJB and ADF Faces RC: How to Create a SelectOneChoice with Value Bound to an Object Property

There has been a lot of blog post with regards to creating SelectOneChoice in ADF Faces RC but all are bound to a data control based on ADF Business Components . In this post, I will try show you how to create a selectOneChoice component if you want to bound the value to an object property (not just mapping simple data types like String, Long, etc.).
Please see below a demonstrative code snippet being ConversionRate as the object to be edited or created and the CurrencyFrom and CurrencyTo are the object attributes of ConversionRate that will be implemented as SelectOneChoice:
<af:selectOneChoice value="#{bindings.findConversionRateByIdIterator.currentRow.dataProvider.currencyFrom}"
                       label="CurrencyFrom"
                       required="true" id="soc1"
                       autoSubmit="true">
   <f:selectItems value="#{myBackingBean.currencyItems}"
                     id="si1"/>
</af:selectOneChoice>
<af:selectOneChoice value="#{bindings.findConversionRateByIdIterator.currentRow.dataProvider.currencyTo}"
                          label="CurrencyTo"
                          required="true" id="soc2"
                          autoSubmit="true">
     <f:selectItems value="#{myBackingBean.currencyItems}"
                       id="si2"/>
</af:selectOneChoice>
The trick on this is the "currentRow.dataProvider" thing. Replace the "findConversionRateByIdIterator" above with your own applicable iterator.

Please see below a dummy backing bean class to enforce illustration of the idea:
package blogspot.soadev.view.backing;

import java.util.ArrayList;
import java.util.List;
import oracle.binding.BindingContainer;
import oracle.binding.OperationBinding;
import javax.faces.model.SelectItem;

public class MyBackingBean {
  private List<SelectItem> currencyItems;
  public List<SelectItem> getCurrencyItems() {
      if (currencyItems == null) {
          List<Currency> currencyList = getCurrencyList();
          currencyItems = new ArrayList<SelectItem>();
          for (Currency currency : currencyList) {
              currencyItems.add(new SelectItem(currency, currency.getCode()));
          }
      }
      return currencyItems;
  }
    public List<Currency> getCurrencyList() {
        //findAllCurrencies is methodAction binding
        return (List<Currency>)getOperationBinding("findAllCurrencies").execute();
    }

  public OperationBinding getOperationBinding(String operation) {
    BindingContainer bindings =
      (BindingContainer)JSFUtils.resolveExpression("#{bindings}");
    return bindings.getOperationBinding(operation);
  }
}
class Currency {
  private String code;
  private String description;

  public void setCode(String code) {
    this.code = code;
  }

  public String getCode() {
    return code;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public String getDescription() {
    return description;
  }
}
class ConversionRate{
  private Currency currencyFrom;
  private Currency currencyTo;
  private Double rate;

  public void setCurrencyFrom(Currency currencyFrom) {
    this.currencyFrom = currencyFrom;
  }

  public Currency getCurrencyFrom() {
    return currencyFrom;
  }

  public void setCurrencyTo(Currency currencyTo) {
    this.currencyTo = currencyTo;
  }

  public Currency getCurrencyTo() {
    return currencyTo;
  }

  public void setRate(Double rate) {
    this.rate = rate;
  }

  public Double getRate() {
    return rate;
  }
}

Saturday, December 26, 2009

EJB Security: Logging the user that invokes a session bean method

If you have a requirement to log the user who created or updated a certain record. You can do so by getting the CallerPrincipal object in the SessionContext of an EJB session bean. The SessionContext can be injected in a session bean using the @Resource annotation. Please see below a sample session bean with an injected SessionContext plus the call to get the CallerPrincipal object:
package oracle;

import java.util.List;
import javax.annotation.Resource;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless(name = "HRFacade", mappedName = "HR_EJB_JPA_App-EJBModel-HRFacade")
@Remote
@Local
public class HRFacadeBean implements HRFacade, HRFacadeLocal {
    @PersistenceContext(unitName="EJBModel")
    private EntityManager em;
    @Resource
    private SessionContext context;

    public HRFacadeBean() {
    }
    public Employee mergeEmployee(Employee employee) {
        String username = context.getCallerPrincipal().getName();
        employee.setUpdatedBy(username);
        return em.merge(employee);
    }
...
}

Friday, December 25, 2009

Integrating JSR 303 Bean Validation with Oracle ADF 11g

In this post, I will try to show you how we were able to successfully integrate the JSR 303 Bean Validation into our ADF 11g Application built with EJB/JPA. The result is a centralized area to define validation constraints using annotations which can be invoked from any layer of the application.

Below is the screen-shot of a sample edit page created with the JSR 303 Bean Validation:
To apply JSR 303 Bean Validation a project, we need to do the following steps:
  1. Download the JSR 303 reference implementation from Hibernate.
  2. Add the 5 jar files into your Model project's Libraries and Classpath (Project Properties).
  3. Annotate your entities with validation annotations like the sample code snippet below:
    ...
    import javax.validation.constraints.DecimalMax;
    import javax.validation.constraints.Max;
    import javax.validation.constraints.Size;
    ...
    public class Employee implements Serializable {
        @Id
        @Column(name="EMPLOYEE_ID", nullable = false)
        private Long employeeId;
        @Column(name="FIRST_NAME", length = 20)
        @Size(min = 3, max = 20)
        private String firstName;
        @Column(name="LAST_NAME", nullable = false, length = 25)
        @Size(min = 3, max = 20)
        private String lastName;
        @Max(1000000)
        private Double salary;
        @Column(name="COMMISSION_PCT")
        @DecimalMax("1.00")
        private Double commissionPct;
    ...
    
  4. Create a utility class that will handle extraction of validation messages like the one below:
    package com.blogspot.soadev.util;
    
    import java.util.Set;
    import javax.validation.ConstraintViolation;
    import javax.validation.Validation;
    import javax.validation.ValidatorFactory;
    
    public class MyUtils {
        public static javax.validation.Validator getValidator() {
    
            ValidatorFactory factory =
                Validation.buildDefaultValidatorFactory();
            return factory.getValidator();
        }
    
        public static String extractConstraintViolationMessages(Set violations) {
            StringBuilder builder = new StringBuilder();
            for (Object obj : violations) {
                if (obj instanceof ConstraintViolation) {
                    builder.append(((ConstraintViolation)obj).getMessage());
                    builder.append("\n");
                }
            }
            return builder.toString();
        }
        //This method returns a set of validation constraint errors
    
        public static Set validateEntity(Object object) {
            javax.validation.Validator validator = getValidator();
            return validator.validate(object);
        }
        // returns null if no violation
    
        public static String getEntityValidationErrorMsg(Object object) {
            Set violations = validateEntity(object);
            if (violations.size() > 0) {
                return extractConstraintViolationMessages(violations);
            }
            return null;
        }
    }
    
  5. In the ViewController project, create the following class that implements javax.faces.validator.Validator.
    package com.blogspot.soadev.view.validator;
    import com.blogspot.soadev.util.MyUtils;
    import com.blogspot.soadev.view.util.JSFUtils;
    import java.util.Set;
    import javax.el.ELException;
    import javax.faces.FacesException;
    import javax.faces.application.FacesMessage;
    import javax.faces.component.EditableValueHolder;
    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import javax.faces.validator.Validator;
    import javax.faces.validator.ValidatorException;
    import javax.validation.ConstraintViolation;
    import javax.validation.Validation;
    
    public class BeanValidator implements Validator {
        private static final String DOT_REGEX = "[.]";
        private static final String BINDINGS = "bindings";
        private static final String INPUT_VALUE = "inputValue";
        private static final String NAME = "name";
        private static final String EMPTY_STRING = "";
        private static final String END_CURLY_BRACKET = "}";
        private static final String DATA_PROVIDER = "currentRow.dataProvider";
        private static final String DOT = ".";
    
        public BeanValidator() {
            super();
        }
    
        public void validate(FacesContext facesContext, UIComponent component,
                             Object object) throws ValidatorException {
            if (component instanceof EditableValueHolder) {
                // Validate input component
                EditableValueHolder input = (EditableValueHolder)component;
                
                try {
                    String expression =
                        component.getValueExpression("value").getExpressionString();
                    if (null != expression) {
                        Set<ConstraintViolation<Object>> constraintViolations =
                            validateValue(object, expression);
    
                        if (constraintViolations.size() > 0) {
                            input.setValid(false);
                            // send all validation messages.
                            String msg =
                                MyUtils.extractConstraintViolationMessages(constraintViolations);
                            FacesMessage fm =
                                new FacesMessage(FacesMessage.SEVERITY_ERROR, msg,
                                                 null);
                            throw new ValidatorException(fm);
                        }
                    }
                } catch (ELException e) {
                    throw new FacesException(e);
                }
            }
    
        }
    
        private Set<ConstraintViolation<Object>> validateValue(Object object,
                                                                                 String expression) {
            Object targetObject = getTargetObject(expression);
            String property = getProperty(expression);
            javax.validation.Validator validator =
                Validation.buildDefaultValidatorFactory().getValidator();
            Set constraintViolations =
                validator.validateValue(targetObject.getClass(), property, object);
            return constraintViolations;
        }
        public String getProperty(String expression){
            if (expression.contains(BINDINGS) && expression.contains(INPUT_VALUE)){
               expression =
                    expression.replaceFirst(INPUT_VALUE, NAME);       
                return JSFUtils.resolveExpression(expression).toString();
            }
            String [] tokens = expression.split(DOT_REGEX);
            String result  = tokens[tokens.length-1];
            result = result.replaceAll(END_CURLY_BRACKET, EMPTY_STRING);
            return result;
        }
        
        public Object getTargetObject(String expression){
            if (expression.contains(BINDINGS) && expression.contains(INPUT_VALUE)){
                expression =
                    expression.replaceFirst(INPUT_VALUE, DATA_PROVIDER);
                return JSFUtils.resolveExpression(expression);
            }
                String [] tokens = expression.split(DOT_REGEX);
                StringBuilder builder = new StringBuilder(tokens[0]);
                for (int i = 1; i < tokens.length - 1; i++){
                    builder.append(DOT);
                    builder.append(tokens[i]);
                }
                builder.append(END_CURLY_BRACKET);
                return JSFUtils.resolveExpression(builder.toString());        
        }
    }
    
  6. Add the JSR303BeanValidator class above to the list of validators in faces-config.xml
  7. Apply the JSR303BeanValidator to your input components in ADF Faces.
    <af:inputText value="#{bindings.firstName.inputValue}"
                                        label="#{bindings.firstName.hints.label}"
                                        required="#{bindings.firstName.hints.mandatory}"
                                        columns="#{bindings.firstName.hints.displayWidth}"
                                        maximumLength="#{bindings.firstName.hints.precision}"
                                        shortDesc="#{bindings.firstName.hints.tooltip}"
                                        id="it2" autoSubmit="true">
                            <f:validator validatorId="JSR303BeanValidator"/>
                          </af:inputText>
                          <af:inputText value="#{bindings.lastName.inputValue}"
                                        label="#{bindings.lastName.hints.label}"
                                        required="#{bindings.lastName.hints.mandatory}"
                                        columns="#{bindings.lastName.hints.displayWidth}"
                                        maximumLength="#{bindings.lastName.hints.precision}"
                                        shortDesc="#{bindings.lastName.hints.tooltip}"
                                        id="it4" autoSubmit="true">
                            <f:validator validatorId="JSR303BeanValidator"/>
                          </af:inputText>
                          <af:inputText value="#{bindings.salary.inputValue}"
                                        label="#{bindings.salary.hints.label}"
                                        required="#{bindings.salary.hints.mandatory}"
                                        columns="#{bindings.salary.hints.displayWidth}"
                                        maximumLength="#{bindings.salary.hints.precision}"
                                        shortDesc="#{bindings.salary.hints.tooltip}"
                                        id="it3" autoSubmit="true">
                            <f:validator validatorId="JSR303BeanValidator"/>
                            <af:convertNumber groupingUsed="false"
                                              pattern="#{bindings.salary.format}"/>
                          </af:inputText>
    
  8. Run your project and try to input invalid values. To display the validation error messages after you tab out of a component, ensure to set the "AutoSubmit" attribute of the component to true.


To know more about JSR 303, click here and here.

Related Posts

ADF Security: The Two Most Useful Security Expression - #{securityContext.regionViewable[''] and #{securityContext.taskFlowViewable['']

If you have a requirement to conditionally display a tab, a link, or a toolbar button to prevent navigation to a protected page allowed only for some specific roles then I bet that the following security expression will satisfy your need:
1)#{securityContext.regionViewable['your.page.targetPageDef']}

Chris Muir has a nice blog about conditionally displaying the global tabs of the ADF UI Shell in which I was able to comment: ADF UI Shell + ADF Security.

But if your requirement is to conditionally display a menu or a toolbar that will launch a bounded task flow (just like the in the dynamic UI Shell) then the following security expression is what you'll need:
2) #{securityContext.taskFlowViewable['/WEB-INF/yourTaskFlow.xml#yourTaskFlow']}

The expressions above will return true if you have the applicable permission, so you can use it in the rendered property of your button, tab, link, or menu. But if your requirement is to disable a component then use "!" the negation operator.

It is also likely that you will need to check the permission programmatically just like when you are a creating a dynamic tree menu based on user roles. Please see the methods below for the translation of the EL security expressions above to pure Java:
import oracle.adf.controller.security.TaskFlowPermission;
import oracle.adf.share.ADFContext;
import oracle.adf.share.security.SecurityContext;
import oracle.adf.share.security.authorization.RegionPermission;
//class declaration
...
    public boolean isRegionViewable(String pageDef) {
        if (pageDef == null) {
            return false;
        }
        RegionPermission permission =
            new RegionPermission(pageDef, RegionPermission.VIEW_ACTION);
        SecurityContext ctx = ADFContext.getCurrent().getSecurityContext();
        return ctx.hasPermission(permission);
    }

    public boolean isTaskFlowViewable(String taskflowId) {
        if (taskflowId == null) {
            return false;
        }
        TaskFlowPermission permission =
            new TaskFlowPermission(taskflowId, TaskFlowPermission.VIEW_ACTION);
        SecurityContext ctx = ADFContext.getCurrent().getSecurityContext();
        return ctx.hasPermission(permission);
    }
...
Many thanks to John Stegeman for helping me figure this out.

Oracle UI Shell: Passing Parameters to a Bounded Task Flow

The discussion below is taken from my feedback on the ADF UI Patterns in OTN forum, I just copied it here for my reference:

Hi!

I have already figured out how to pass parameters to my bounded taskflow that I intend to launch on a separate tab. It would be the same way as how the UI Shell framework passes the TabContext object to the interested taskflows. This cannot be done though without extending the dynamicTabShellDefinition.xml. I am thinking, that this pertinent requirement can easily be supported by just pre-configuring the dynamic "parametersMap" attribute of the taskFlow binding definition to a value like "#{viewScope.parametersMap}". In this case, if I have something that I need to pass as parameter to my bounded taskflows, I just need to put the object on the parametersMap in view scope. I need to test this yet though. Below is a quotation from the Fusion Developers' Guide about the parameterMap:
The <parameterMap> element specifies an EL expression that returns a java.Util.map object. The object contains task flow input parameter name/value pairs.
I have already tested my understanding on the taskFlow binding "parametersMap" attribute above and it works! First, I added an additional parameter in line with the tabContext parameter to my custom dynamicTabShellDefinition.xml. The parameter binding section will be as follows:
<parameters>
   <parameter id="tabContext" value="${viewScope.tabContext}"/>
   <parameter id="parameterMap" value="${requestScope.parameterMap}"/>
</parameters>
Note that instead of using ${viewScope.parameterMap}, I used ${requestScope.parameterMap} because it seems that when I passed a viewScope parameter from a backingBean inside one of my bounded task flows, it will not reach the initialization of my target task flow in the separate tab. Second, I redefined all my taskFlow bindings to define the "parametersMap" attribute value to "#{bindings.parameterMap}". Please see below a redefined taskFlow definition:
<taskFlow id="r0"
    taskFlowId="${viewScope.tabContext.taskflowIds[0]}"
    activation="deferred"
    xmlns="http://xmlns.oracle.com/adf/controller/binding"
    parametersMap="#{bindings.parameterMap}">
<parameters>
<parameter id="tabContext" value="${bindings.tabContext}"
         xmlns="http://xmlns.oracle.com/adfm/uimodel"/>
</parameters>
</taskFlow>
With the steps above, I could already define any parameter that I need in the bounded taskflow: Please see below for a sample parameter definition:
<input-parameter-definition id="__2">
  <name id="__3">employeeId</name>
  <value>#{pageFlowScope.employeeId}</value>
  <required/>
</input-parameter-definition>
Just be sure that before you invoke the backing bean method that will call the TabContext addTab() method you already put the employeeId into the parameterMap and set the parameterMap into requestScope:
...
Map<String, Object> parameterMap = new HashMap<String, Object>();
parameterMap.put("employeeId",employee.getId());
JSFUtils.setRequestAttribute("parameterMap", parameterMap);//JSFUtils is a utility class from FOD
//direct or indirect call to the TabContext addTab() method here

Saturday, July 18, 2009

unable to startup the Resource Adapter specified in the element: location='eis/Jms/TopicConnectionFactory'

Problem: Exception occured when binding was invoked.

Exception occured during invocation of JCA binding: "JCA Binding execute of Reference operation 'Produce_Message' failed due to: JCA Binding Component connection issue. JCA Binding Component is unable to create an outbound JCA (CCI) connection. OrderBookingComposite:FulfillmentBatch [ Produce_Message_ptt::Produce_Message(purchaseOrder) ] : The JCA Binding Component was unable to establish an outbound JCA CCI connection due to the following issue: BINDING.JCA-12510 JCA Resource Adapter location error. Unable to locate the JCA Resource Adapter via .jca binding file element The JCA Binding Component is unable to startup the Resource Adapter specified in the element: location='eis/Jms/TopicConnectionFactory'. The reason for this is most likely that either 1) the Resource Adapters RAR file has not been deployed successfully to the WebLogic Application server or 2) the '' element in weblogic-ra.xml has not been set to eis/Jms/TopicConnectionFactory. In the last case you will have to add a new WebLogic JCA connection factory (deploy a RAR). Please correct this and then restart the Application Server ". The invoked JCA adapter raised a resource exception. Please examine the above error message carefully to determine a resolution.
Solution: Add the required connection pool
'eis/Jms/TopicConnectionFactory'.
Refer to the following link:
Tutorial for Running and Building an Application with Oracle SOA Suite

Monday, July 13, 2009

Error Running "populateImages" Ant Target of the Oracle FOD Infratructure Application

I wonder why my FusionOrderDemo StoreFrontModule user interface do not display the product images. I re-run the MasterBuildScript build.xml of the Infrastructure application bundled in the FusionOrderDemo_R1 and noted that the populateImages target raises an exception and that is another "timezone region not found error". I have encountered this of error before and documented it in my earlier blog but even though that I already set the appropriate "-Duser.timezone=GMT" java option on the Run properties of each of the project, the error still persisted. It seems that JDeveloper do not read the java options that I've set when the class is called from Ant.

To cut the story short, here are the steps that solved the problem:

1) Open the build. xml file @ DatabaseSchema>Resources>build.xml.

2) Replace the script of the populateImages target with the following:
<target name="populateImages" depends="compileImagesApp">
    <java classname="oracle.fodemo.share.imageloader.LoadImages" fork="true" failonerror="true" >
    
      <classpath refid="schema.classpath"/>
      <classpath refid="oracle.jdbc.path"/>
      <classpath>
        <pathelement location="classes/"/>
      </classpath>
      <arg value="${jdbc.url}"/>
      <arg value="${db.demoUser}"/>
      <arg value="${db.demoUser.password}"/>
      <arg value="${imageHome}"/>
      <jvmarg value="-Duser.timezone=GMT"/>
    </java>
  </target>
3) Open the ImageLoaderServiceAMImpl class @ DatabaseSchema>ApplicationSources>oracle.fodemo.share>imageloader>ImageLoaderServiceAMImpl

4) Look for something like the following code:
imagesUrl = getClass().getClassLoader().getResource(imageDirectory + subDirectory); // imagesUrl = new URL("file:///C:\\JDeveloper\\tutorial\\FusionOrderDemo_R1\\Infrastructure\\DBSchema\\Images\\thumbnails\\");

5) Comment this code: imagesUrl = getClass().getClassLoader().getResource(imageDirectory + subDirectory);

6) Uncomment this code: /
/ imagesUrl = new URL("file:///C:\\JDeveloper\\tutorial\\FusionOrderDemo_R1\\Infrastructure\\DBSchema\\Images\\thumbnails\\");

7) Replace the above directory "C:\\JDeveloper\\tutorial" with the absolute address of your directory containing the FusionOrderDemo_R1 folder.

8) Re-run the build.xml file of the MasterBuildScript project.

Tags: FusionOrderDemo_R1, JDeveloper, 11g, Fusion Order Demo

Saturday, July 11, 2009

Error Deploying to Stand Alone WebLogic Server -"java.lang.ClassNotFoundException: oracle.adf.library.webapp.ResourceServlet", "Deployment incomplete"

To avoid the following error :"java.lang.ClassNotFoundException: oracle.adf.library.webapp.ResourceServlet", deploy the application on the application context and not only on the UI project. To avoid the "Deployment Incomplete" error, try to disable proxy settings. To avoid more errors in deploying the Fusion Order Demo to a stand alone WebLogic Server 11g , refer to the following tutorial: Deploying a JDeveloper SOA Application to Oracle WebLogic Server 11g Refer also to my earlier post on - timezone region not found. Tags: JDeveloper 11g R1 WebLogic

Wednesday, July 8, 2009

Error in Running Repository Creation Utility (RCU) While Using Oracle XE database

While following the Quick Installation Guide for Oracle SOA Suite11g Release 1, I encountered the following error in running the Repository Creation Utility while using Oracle XE database.

ERROR rcu: oracle.sysman.assistants.rcu.backend.task.PrereqTask::execute: Prereq Evaluation Failed oracle.sysman.assistants.rcu.backend.validation.PrereqException: RCU-6083:Failed - Check prerequisites requirement for selected component:SOAINFRA Please refer to RCU log at C:\installers\Development\Active\rcuHome\rcu\log\logdir.2009-07-08_16-16\rcu.log for details. at oracle.sysman.assistants.rcu.backend.validation.PrereqEvaluator.executePrereqTask(PrereqEvaluator.java:600) at oracle.sysman.assistants.rcu.backend.task.PrereqTask.execute(PrereqTask.java:68) at oracle.sysman.assistants.rcu.backend.task.ActualTask.run(TaskRunner.java:303) at java.lang.Thread.run(Thread.java:619) 2009-07-08 16:34:49.848 ERROR rcu: oracle.sysman.assistants.rcu.backend.task.ActualTask::run: RCU Operation Failed oracle.sysman.assistants.common.task.TaskExecutionException: RCU-6083:Failed - Check prerequisites requirement for selected component:SOAINFRA Please refer to RCU log at C:\installers\Development\Active\rcuHome\rcu\log\logdir.2009-07-08_16-16\rcu.log for details. RCU-6107:DB Init Param Prerequisite failure for: processes Required Value = 200, Current Value = 40, Comparison Operator: ">=" at oracle.sysman.assistants.rcu.backend.task.PrereqTask.execute(PrereqTask.java:76) at oracle.sysman.assistants.rcu.backend.task.ActualTask.run(TaskRunner.java:303) at java.lang.Thread.run(Thread.java:619)

Solution:
Run SQL Command Line
Connect as SYSDBA using user "system"
SQL> connect system/password
SQL> show parameters processes
SQL> alter system set processes=200 scope=spfile;

And dont forget to restart your database...(thanks Attila for reminding me).
For more info, see the following site: Oracle XE Tuning Tags: JDeveloper 11g R1 WebLogic SOA Suite Repository Creation Utility

Wednesday, June 17, 2009

How the ADF PageLifeCycle come into the picture in ADF 11g?

I was wondering how the enhanced ADF PageLifeCycle come into the picture in Oracle ADF 11g when I noted that there was no phase listener configured in faces-config.xml, and specially that I have read the one stated in Oracle® Application Development Framework Developer’s Guide 10g Release 3- "When an ADF Faces component bound to an ADF data control is inserted into a JSF page for the first time, JDeveloper adds the ADF PhaseListener to faces-config.xml." - But I do not see this in faces-config.xml in the StoreFront demo, so I posted a new thread in OTN forums and happy to received a prompt answer which directed me to the right direction. (click the following: Why ADFPhaseListener not configured in faces-config.xml in JDeveloper 11g?) Well, to give you more idea on how the enhanced ADF PageLifeCycle came into the picture in ADF 11g, below are the details:
  1. The Faces Servlet is defined and mapped in the web.xml file.
  2. The Faces Servlet reads the faces-config.xml.
  3. The ADFPhaseListener is configured in an internal faces-config.xml in META-INF of adf-controller.jar in 11g.
  4. The ADFPageLifeCycle is instantiated through the ADFPhaseListener.

Tuesday, June 16, 2009

Troubleshooting JDeveloper Out of Memory Error - Perm Gen Size/ Space

This is another usual error encountered when deploying projects to embedded WebLogic Server in JDeveloper 11g. I have done my searching to google and lost myself on the many lengthy discussion.
To make the life of others easy, here is the solution that I have got:

Change the PermGen size for your internal WLS in \jdeveloper\system\system11.1.1.0.31.51.88\DefaultDomain\bin\setDomainEnv.cmd
Find the line with MEM_MAX_PERM_SIZE.
set MEM_MAX_PERM_SIZE=-XX:MaxPermSize=128m
Increase it to 256m or 512m. 






An update to this post:
The solution above will just postpone the the raising of the error because of the bigger perm size capacity and not fully solve the issue.
The right solution so far is to leverage the JRockit JVM as told on the following thread:
Another different solution to the "PermGen space issue" -comments solicited

Error running project in JDeveloper - "java.sql.SQLDataException: ORA-01882: timezone region not found"

I always encountered this error when I started learning Oracle ADF in JDeveloper and had found no straightforward answer in the forums. Now that I was able to find the solution through a similar case in Metalink, I thougth that it would help other beginners like me, if I will post the solution here. Error: java.sql.SQLDataException: ORA-01882: timezone region not found Error: java.lang.NumberFormatException: For input string: "" Solution: add a java option "-Duser.timezone=GMT" without the quotes in the run configuration under project properties on every project in JDeveloper. It is also important to restart the Server after configuring such java option. Tags: JDeveloper 11g R1 WebLogic

ORACLE FUSION MIDDLEWARE 11g ONLINE LAUNCH

Huh!!! Oracle Fusion 11g will be launched finally! After knowing yesterday that the Oracle Fusion Middleware 11g is scheduled to be launched on July 1st to Oracle Partners, I am happy to received today an email invitation from Oracle to register for the online launch (this is the link) which is scheduled on July 9. This is one great news to our Java Development Team for this Fusion 11g has been delayed for sometime and that current JDeveloper 11g has no integrated BPEL designer yet. Well, I am excited to attend to this web cast and see how this will finally solve our issue on leveraging both ADF Faces 11g and BPEL in our upcoming project.