Showing posts with label ADF. Show all posts
Showing posts with label ADF. Show all posts

Sunday, August 2, 2015

Using setWhereClause in ADFBC properly

Avoid SQL Injection in ADFBC.
Securely using ADFBC.

ADF BC is a robust framework that lets developers simplify code for Data Access in ADF Application.  ADF does a great Job by using prepared statements across all SQLs it generates. Thus improving security of the application. 
ADF developers are also given a access to write their own where clause on a view Object using the setWhereClause method on View Object.
Most developers tend to misuse this method by typing in statements by appending strings. Which can be used to inject SQL
for e.g.
Wrong Way
vo.setWhereClause(OrderNumber = ‘”+   pOrderNo  + “’”)
vo.executeQuery()



The best way to use this method securely is

Correct Way

vo.setWhereClause(OrderNumber = ?)
vo.setWhereClauseParams(new Object[] { pOrderNo  });
vo.executeQuery()
vo.setWhereClauseParams(null);

Tuesday, June 23, 2015

How to Deploy ADF10g applications on Weblogic 12C.

You might ask me why, we had a scenario where it’s easier to manage fewer variety of application servers.  legacy 10g applications will be replaced by new applications in a couple of years. Until then reduce infrastructure’s load.

Weblogic Server Setup.

You might ask me why, we had a scenario where it’s easier to manage fewer types of application servers.  And it was too expensive to re write legacy 10g applications and decided to let some new systems take over the old applications. Until then reduce infrastructure team’s load and their ability to train. 

  1. Create a basic Weblogic domain. And add clusters and servers as required

    image
  2. Once the servers are set up and running.

    If you need JDeveloper to be able to deploy directly to the server
    Go to the admin console and select servers and go to Protocols - > HTTP and check “Enable Tunneling”.
    This is only needed if you want to deploy from jdeveloper 10.1.3 directly

    image
  3. Create necessary data sources for the application.







JDeveloper 10.1.3.4 setup



You need Weblogic 9.x‘s weblogic.jar to configure JDeveloper 10g to be able to deploy directly to Weblogic 12c.  I was able to find it in DOC ID 1401953.1.


  1. Copy the Weblogic.jar (Weblogic 9.x) from Weblogic server/lib directory to /jdev/lib/ext directory in JDeveloper 10g.

    You can create a Weblogic 9.2 connection and point the server to 12c to be able to deploy as illustrated in the images below

    image

    image

    image

    image












ADF 10g Application Setup.

Couple of problems I faced was some JSF and Oracle libraries were loaded through Weblogic.jar. When I added the 10g libraries in the CLASSPATH, some of the classes were loaded earlier as a part of Weblogic.jar and causing problems. Adding a PRE-CLASSPATH was not helping as Weblogic need the latest version of some jars files to start up. So the only option I found was to load the required libraries as a part of WEB-INF lib for 12c. In case of Weblogic 10.x you could load the required libraries as a part of CLASSPATH.


  1. Add required Weblogic descriptors.
    Add weblogic.xml in WEB-INF.
  2. Add the required jars in the application classpath
    I added the below jars in the classpath

    adf-connections.jarbc4jctejb.jarconcurrent.jarojdbc6dms.jarordhttp.jartranslator.jar
    adfbinding.jarbc4jdomorcl.jardc-adapters.jarojdl.jarordim.jarwsclient.jar
    adfcm.jarbc4jimdomains.jardms.jarojmisc.jarosdt_cert.jarwsdl.jar
    adfm.jarbc4jmt.jarhttp_client.jarojpse.jarosdt_core.jarwssecurity.jar
    adfmweb.jarbc4jmtejb.jarjazncore.jaroracle-el.jarosdt_saml.jarxml.jar
    adfs-jazn.jarbc4jsyscat.jarjdev-cm.jaroraclepki.jarosdt_wss.jarxmlef.jar
    adfs.jarcache.jarjsp-el-api.jarorajaxr.jarosdt_xmlsec.jarxmlparserv2.jar
    adfshare.jarcollections.jarmdds.jarorasaaj.jarruntime12.jarxsdlib.jar
    antlr.jarcommons-cli-1.0.jarmdsrt.jarorawsdl.jarshare.jarxsqlserializers.jar
    bc4jct.jarcommons-el.jarojdbc6.jarorawsrm.jartoplink.jarxsu12.jar
    adfmtl.jaradfui.jarbc4jdomgnrc.jar
  3. Make sure you have the below tag in the Weblogic.xml
    <container-descriptor>
    <prefer-web-inf-classes>false</prefer-web-inf-classes>
    <prefer-application-packages>
    <package-name>javax.faces.*</package-name>
    <package-name>com.sun.faces.*</package-name>
    <package-name>com.bea.faces.*</package-name>
    <package-name>oracle.*</package-name>
    </prefer-application-packages>
    <prefer-application-resources>
    <resource-name>javax.faces.*</resource-name>
    <resource-name>com.sun.faces.*</resource-name>
    <resource-name>com.bea.faces.*</resource-name>
    <resource-name>META-INF/services/javax.servlet.ServletContainerInitializer</resource-name>
    </prefer-application-resources>
    </container-descriptor>


Debugging Weblogic 12c applications using JDeveloper 10g.


I use remote Debugger. Since the Weblogic was running on my local machine. I did not find any lag and it was smooth.
Below are the steps to add remote debugging


  1. Change startWebLogic.cmd to add the below line
    set JAVA_OPTIONS=-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=n

    image
  2. Restart your Weblogic for this to take effect.
  3. Now in JDeveloper. Right click on the project you want to debug. And click on Run/Debug and Edit as in the image below.
    image
  4. Check Remote Debugging and Profile

    image
  5. Click on the Remote

    Change Protocol to “Attach with JPDA”
    Give the host and leave defaults for the other.
    image
  6. When you want to debug. You can right click on the class you want to debug and hit “Start remote Debugger”.
    image


































































Tuesday, May 20, 2014

Creating Mbeans(JMX) in ADF Application and accessing them from jrockit mission control



Mbeans(JMX) can be very useful to manage an application or any resource. ADF provides some inbuilt mbeans. These can be enabled by adding the below tags in web.xml
<listener>
   <listener-class>
        oracle.adf.mbean.share.connection.ADFConnectionLifeCycleCallBack
   </listener-class>
</listener>
<listener>
   <listener-class>
        oracle.adf.mbean.share.config.ADFConfigLifeCycleCallBack</listener-class>
</listener>
<listener>
   <listener-class>
        oracle.bc4j.mbean.BC4JConfigLifeCycleCallBack</listener-class>
</listener>


Some times you might want to add custom Mbeans to control your application. You also might want to access these using your jrockit mission control. Lets understand this by take an instance of changing log levels of certain classes when you use log4j for logging using mbeans(JMX).
 
1. First you need an interface of the methods you want to expose.
public interface Log4jConfigMBean {
    public String fetchLogLevel(String logger);
    public String changeLogLevel(String level, String logger);
}

 
2. You need a class that implements the previously created Log4jConfigMBean and javax.management.MBeanRegistration
package com.test.backing;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.ObjectName;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class Log4jConfig implements Log4jConfigMBean , MBeanRegistration {
    public Log4jConfig() {
        super();
    }

    public String fetchLogLevel(String name) {
        if (name==null ||"".equals(name) )
        {
          return "invalid usage";
        }
        else
        {
          return  "Log level of " +name +" is "+ (Logger.getLogger(name).getLevel()!= null ?Logger.getLogger(name).getLevel() :Logger.getRootLogger().getLevel());
        }
    }

    public String changeLogLevel(String level, String name) {
        if (name==null ||"".equals(name)|| level==null || "".equals(level) )
        {
          return "invalid usage";
        }
        else
        {
          Logger logger = Logger.getLogger(name);
          logger.setLevel(Level.toLevel(level));
          return  "Log level of "+ name + " set to " +Logger.getLogger(name).getLevel();
        }
    }

    public ObjectName preRegister(MBeanServer mBeanServer, ObjectName objectName) {
        return null;
    }

    public void postRegister(Boolean boolean) {
    }

    public void preDeregister() {
    }

    public void postDeregister() {
    }
}


3. We have to register these in someplace when the application starts. I chose initialize these using a ServletContextListener. You can use other methods too.

package com.test.backing;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;

import javax.naming.InitialContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class Log4jMBeanLifeCycleListener implements ServletContextListener {
    public Log4jMBeanLifeCycleListener() {
        super();
    }

    public void contextInitialized(ServletContextEvent servletContextEvent) {
        try {
            InitialContext ctx = new InitialContext();
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
            Log4jConfig mbean = new Log4jConfig();
            ObjectName oname;
            oname = new ObjectName("Log4j:type=Log4jConfig,name=RuntimeLog4jConfig");
            mbs.registerMBean(mbean, oname);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    }
}


4. Add the ServletContextListener to the web.xml
<listener>
  <listener-class>com.test.backing.Log4jMBeanLifeCycleListener</listener-class>
</listener>

 
 
5. Testing the mbeans.

a. Make sure you have enabled JMX on the weblogic server. In Jdeveloper you can add them to the Run Configurations
-Dcom.sun.management.jmxremote -Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true -Dcom.sun.management.jmxremote.port=7772
image
b. Start jrockit. You can now see the new Management Extension. You can change the log level in runtime.
image































Friday, September 6, 2013

Enabling ADF for Weblogic Clustering

To Enable ADF Application to be clusterable

1.  Any object that might be replicated to another instance of the server, should be Serializable.
  • The most common ones are the backing beans. 
  • ADF UI Components are not serializable, to over come this problem don't bind UI Components to Backing Beans.

2. ADF BC State Management should be enabled. Activation and Passivation should be done to a place where all the server instances can access the data. Preferably to a database.
 set jbo.dofailover = true in Application module to true.

3. in      Weblogic-application.xml
Change the Persistent store type to REPLICATED_IF_CLUSTERED

1.       adf-config.xml
Check the box “High Availability for ADF Scopes”

Wednesday, July 10, 2013

ADF disclosed property problems in showDetailItem after enabling MDS


After MDS is enabled in ADF, If you have logic to show or hide showDetailItem using  tab.setDisclosed(), it might not work.

To solve this issue.
import org.apache.myfaces.trinidad.change.AttributeComponentChange;
import org.apache.myfaces.trinidad.change.ChangeManager;
import org.apache.myfaces.trinidad.change.ComponentChange;
import org.apache.myfaces.trinidad.context.RequestContext;


ChangeManager changeManager = RequestContext.getCurrentInstance().getChangeManager(); ComponentChange disclosed = new AttributeComponentChange("disclosed",Boolean.TRUE); ComponentChange undisclosed = new AttributeComponentChange("disclosed",Boolean.FALSE); changeManager.addComponentChange(FacesContext.getCurrentInstance(), tabA,disclosed); changeManager.addComponentChange(FacesContext.getCurrentInstance(), tabB,undisclosed); AdfFacesContext.getCurrentInstance().addPartialTarget(tabA); AdfFacesContext.getCurrentInstance().addPartialTarget(tabB);


Tuesday, July 2, 2013

MDS ( metadata ) customizations written to the store but does not apply to components when the user comes back to the page in ADF.


Just noticed the below in ADF 11.1.1.*.
ADF MDS customizations are not applied to components but written to store when we have the below snippet in web.xml.
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>oracle.jsp.runtimev2.JspServlet</servlet-class>
</servlet>

Thursday, June 20, 2013

How to display ADF application in an iframe



Add the below code to web.xml to
<context-param>
<param-name>oracle.adf.view.rich.security.FRAME_BUSTING</param-name>
<param-value>never</param-value>
</context-param>
 
Note This can make the application vulnerable to clickjacking

Wednesday, December 19, 2012

ADF Mobile: Displaying error, warning, info messages


Every application will have scenarios to display different kinds of error and information messages on the screen. ADF Messages on mobile devices are displayed as a popup with a single close button

This demo application RedstackLogicMessagesDemo.rar has simple code to throw different kind of messages on to the screen when some buttons are clicked.

to create an error that is thrown onto the screen you can throw a new oracle.adfmf.framework.exception.AdfException. This lets you throw either of  FATAL, ERROR, WARNING, INFO messages on to the screen.

for e.g. to show messages you can create exceptions like this


image




Below is how messages will look in the mobile






image
imageimage
image



Saturday, December 15, 2012

Disable count query in ADF table


This can be done by RowCountThreshold = –1 in the iterator on the page definition

Note: To have a proper scroll behavior. This query should execute.  Scroll behavior will change. It will only scroll the range size.

JDBC Drivers / data source problems for Jdeveloper 11.1.2.


When you upgrade to Jdeveloper 11.1.2.x you might face multiple problems when you are using jdbc data sources as you configured with the 11.1.1.x versions.
You might face problems like this

Caused by: java.lang.AbstractMethodError: com.ibm.as400.access.AS400JDBCConnection.isWrapperFor(Ljava/lang/Class;)Z
    at weblogic.jdbc.wrapper.JDBCWrapperImpl.isWrapperFor(JDBCWrapperImpl.java:202)



Solution:
Weblogic 11.1.2 supports JDBC4.0 by default. So All JDBC drivers should be
JDBC 4.0 compatible.

more about JDBC 4.0 refer http://today.java.net/pub/a/today/2007/04/10/whats-new-in-jdbc-40.html

JDBC 4.0 Drivers
SQL Server : Download  JDBC 4.0  driver from http://www.microsoft.com/en-us/download/details.aspx?id=11774  and use sqljdbc4.jar in your classpath
JTOpen / JT400:  Download JDBC 4.0 driver from http://sourceforge.net/projects/jt400/files/JTOpen-full/7.8/jtopen_7_8_jdbc40_jdk6.zip/download

jars in Domain/lib not Pickedup
Weblogic 11.1.2 doesn’t automatically pick up jars from the the domain lib directory. To fix this, you have to set the class path in the weblogic start command. this can be done in many ways. One way is to edit bin/startWebLogic.cmd and add a line set
CLASSPATH=%SAVE_CLASSPATH%;path to your driver;

Wednesday, October 3, 2012

ADF - How to submit/post values changes to database immediately in ADF UI components


When you want to persist changes to a database as soon as a user changes the value in any of the UI Components. you can use the below technique.

1. Add a value change listener to your UI Component and also make Auto Submit to true.

<af:selectOneChoice value="{row.bindings.reasonCode.inputValue}"
    
label="#{row.bindings.reasonCode.label}" id="soc1" autoSubmit="true"
     valueChangeListener="#{failures.reasoncodeChange}">
       
         <f:selectItems value="#{row.bindings.reasonCode.items}" id="si1"/>
</af:selectOneChoice>


2.  In the Backing bean value change listener method
valueChangeEvent.getComponent().processUpdates(FacesContext.getCurrentInstance());
Calling the the above line will do all the model updates. refer the link
public void reasoncodeChange(ValueChangeEvent valueChangeEvent) {
valueChangeEvent.getComponent().processUpdates(FacesContext.getCurrentInstance());
BindingContainer bindings = getBindings();
OperationBinding operationBinding =bindings.getOperationBinding("Commit");
operationBinding.execute();           
}






Thursday, September 6, 2012

Save MDS data in ADF

try
{
    ADFContext context = ADFContext.getCurrent();
    MDSSession session = (MDSSession)context.getMDSSessionAsObject();
    session.flushChanges();
} catch (MDSIOException e) {
} catch (ConcurrentMOChangeException e) {
} catch (ValidationException e) {
}


Friday, August 24, 2012

How to use ADF MDS without enabling ADF security


MDS needs some way to uniquely identify each logged in user. Sometimes we might have applications that don't use ADF Security. We have to write a custom class that helps MDS to distinguish users. You start with a class that extends oracle.mds.cust.CustomizationClass. You need to modify the code in red to get a unique value that identifies the logged in user.

package a.b.c;
import java.util.Map;import javax.faces.context.FacesContext;import oracle.mds.core.MetadataObject;
import oracle.mds.core.RestrictedSession;
import oracle.mds.cust.CacheHint;
import oracle.mds.cust.CustomizationClass;

public class MyUserCC extends CustomizationClass {
    private static final String DEFAULT_LAYER_NAME = "user";
    private String mLayerName;

    public MyUserCC () {
        mLayerName = "user";
    }

    public CacheHint getCacheHint() {
        return CacheHint.USER;
    }

    public String getName() {
        return mLayerName;
    }

// Change code in this method to get the current logged in user   
public String[] getValue(RestrictedSession sess, MetadataObject mo) {
  String user = null;

// Change the code below to suits your application    FacesContext ctx = FacesContext.getCurrentInstance();
        if (ctx != null) {
          Map sessionState = ctx.getExternalContext().getSessionMap();
          user = (String)sessionState.get("LOGGEDINUSER");
        }
        return  user != null ? new String[]{user} : null;
    }

}
 
 
Application/Project Settings
1. Right click on the ViewController Project
    select ADF View
     Check "Enable User Customizations"
     Select Radio "Across Sessions using MDS"
2. Open adf-config.xml  in the Overview View
In the MDS Configuration Tab
    Click the Add(+) button in Customizations Configurations match Path = "/" and select the Class you just created “a.b.c.MyUserCC”
In the view Tab
    Tags
          Select the tags and the attributes on the tags you want MDS to be enabled on in the application.
 
JSPX/JSFF UI component  Settings
Go to the component you want MDS to work.  Change the attribute persist="ALL" for all properties to work
if you dont want some of them use  dontPersist="displayIndex frozen" (You can use all features you want seperated by a space in both persist and dontPersist attribute. )
























Thursday, January 26, 2012

ADF State Management(Activation Passivation ) to un supported databases

ADF by default supports passivation to a database if the database is oracle. ADF out of the box also supports passivation to a database if the database is DB2 or SQLServer. If any other database is used, State management is done to a file.


Though state management to a file is faster than a database. Persisting to a file does not work well in a clustered application. You will notice a major problems when the application fails over.


To address this situation to use unsupported databases and want to use state management against a database

  1.  Create a  CustomPersistManager class that extends oracle.jbo.pcoll.JDBCPersistManager
    for e.g. refer CustomPersistManager.java
  2. Edit the AM Configurations

    jbo.passivationstore:    database
    jbo.pcoll.mgr:    rohith.custom.CustomPersistManager
    jbo.server.internal_connection: use complete jndi like java:comp/env/jdbc/cnTPSDS
                                                       or jdbc url

You might want to add  "-Djbo.passivationstore=database" to the JVM start params to keep this more stable.