Thursday, 30 April 2009

ADF 11g - Groovy expression for default value of todays date

I have an EO with one Date column which I wanted to default to today's date on record creation. Normally I would create a EO class and add the "create" method to the class to achieve this but I found it's even easier to use a groovy expression which I did as follows.

1. Double click on EO to bring it up in the code editor "Overview" tab.
2. Click on attributes
3. Select the "Date" attribute and press the edit icon
4. Place the following into the "Value" field

String.format('%tF', new Date())

Note: This will ensure we retrieve today's date and format the date into the format which our Date EO attribute is using which in this case is "YYYY-MM-DD".

5. Select the check box "Expression" for the "Value Type"

Note: You can also use the built in Groovy expressions adf.currentDate and adf.currentDateTime that you can use.

6. Press OK.

Now when we create a new record the default value for the date will be todays date using a groovy expression.

You can see from this groovy script that unless we format the output ADF will throw a runtime error with just the use of new Date() without any formatting.

Groovy Script:

def today= new Date() //represents the date and time when it is created
println today

println String.format('%tF', today)

Output:

Thu Apr 30 11:51:54 EST 2009
2009-04-30

More information on groovy and ADF can be found here.

http://www.oracle.com/technology/products/jdev/11/how-tos/groovy/introduction_to_groovy.pdf

Friday, 24 April 2009

Configuring JDeveloper 11g to use Struts 2

I was recently asked how to setup JDeveloper 11g web projects to use Struts 2 here is what I did to get this working. Keep in mind JDeveloper has design time support for Struts 1.x but not Struts 2 so this is a manual process.

1. Start Jdeveloper 11g
2. Select File | New | General | Applications | Generic Application
3. Name the application "Struts2Demo" and click next
4. Name the project "Demo" and press finish

Now at this point we want to add a simple JSP page to the project so
we end up with a web project , we will need to configure this to use
struts2 manually which we will do soon.

5. Right click on the project and select "New | Web Tier | JSP"
6. call the JSP "sayhello.jsp" and append "\pages" to the end of
the directory path so it creates the JSP in a sub directory called
"pages".

At this point you will need to download the Struts libraries. At a minimum,
you will need to put the following in your WEB-INF/lib directory of your
JDeveloper project:

* struts2-core.jar (The framework itself)
* xwork.jar (Struts 2 is built on the XWork 2 framework)
* ognl.jar (Object Graph Notation Language is used throughout the framework)
* freemarker.jar (Freemarker is used to create UI tag templates in Struts 2)
* commons-logging.jar (Used to log to log4j or JDK logging)

Download struts2 from here. I am using 2.1.6 here.

http://struts.apache.org/download.cgi

7. Refresh the navigator to ensure your project shows the WEB-INF\lib folder
and the required struts2 libraries.
8. Double click on the project to invoke project properties dialog and
select "Libraries\Classpath"
9. Add the 5 jars files to the project and press OK. You could create
a single library and add the 5 JAR files to that library if you like.

Now we are ready to configure our project to use struts2.

10. Open up the web.xml and add the following entries


<?xml version = '1.0' encoding = 'windows-1252'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee">
<description>Empty web.xml file for Web Application</description>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>35</session-timeout>
</session-config>
<mime-mapping>
<extension>html</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>txt</extension>
<mime-type>text/plain</mime-type>
</mime-mapping>
</web-app>

11. Create a java class as follows

package demo.struts2.action;

import com.opensymphony.xwork2.ActionSupport;

public class ExampleAction extends ActionSupport
{
private String message;

public String execute() throws Exception
{
this.message = "Hello from Struts 2";
return SUCCESS;
}

public void setMessage(String message)
{
this.message = message;
}

public String getMessage()
{
return message;
}
}

12. Struts places its configuration in a struts.xml file. Create the file
at the root of your source folder for the project as follow. We’ll need
to add our new action to the struts.xml file.

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
<!-- Configuration for the default package. -->
<package name="default" extends="struts-default">
<action name="ExampleAction" class="demo.struts2.action.ExampleAction">
<result name="success">/pages/sayhello.jsp</result>
</action>
</package>
</struts>

13. Finally ensure the "sayhello.jsp" looks as follows

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ page contentType="text/html;charset=windows-1252"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<title>sayhello</title>
</head>
<body>
<h2><s:property value="message" /></h2>
</body>
</html>


Now we need to add the Struts2 tag library to our project.

14. Double click on the project to invoke the project properties and
select "JSP Tag Libraries"
15. Click the "Add" button
16. Select "Project" and then press the "New" button
17. Navigate to "public_html\WEB-INF\lib\struts2-core.jar" and
press 'Open"
18. Verify it finds "Struts tage 2.2.3".
19. Press OK
20. Again double click on the project to invoke the project properties
and select "Java EE Application" and set the context root to "struts2demo"
and press Ok
21. Select File | save All
22. Select Build | Demo.jpr to ensure it compiles fine.
23. Navigate to the default domain directory LIB folder of the integrated server
and add the 5 JAR files we need for struts 2

eg: D:\jdev11g-boxer\jdeveloper\jdev\system11.1.1.0.31.52.05\DefaultDomain\lib

commons-logging-1.0.4.jar
freemarker-2.3.13.jar
ognl-2.6.11.jar
struts2-core-2.1.6.jar
xwork-2.1.2.jar

Now JDeveloper doesn't provide support for running struts2 applications so you
will need to create some sort of index.jsp page which will redirect to our action
we created. Here we will just run the JSP and then alter the URL to invoke
your action so that the view page will render correctly.

23. Right click on "sayhello.jsp" and select "Run" to start the Integrated
WLS.

You will notice it displays nothing , that is due to the fact we have not
run the actual action which we do by altering the URL as follows

http://127.0.0.1:7101/struts2demo/ExampleAction.action

Note: I am not 100% sure why I need to add the struts2 JAR files to
the defualt domain LIB folder of my WLS server as I would expect it to find
those files in the WEB-INF\lib directory of the application which is how
struts1 works and I believe how struts2 should work. I even went back
to JDeveloper 10.1.3 and found that indeed it works there without
having to manilpulate it's classpath which proves the files in WEB-INF\lib
of the application is all that is needed.

Not sure why WLS doesn't work that way?

Friday, 17 April 2009

How to Add Row Filtering to an af:table which wasn't setup initially for this

When you add an ADF Read Only table to a JSF page you can add "Row Filtering" to the table. Here is how to set this on a table which was not setup with "Row Filtering" and you now wish to enable it now.

1. Right click on the JSF page which contains the "af:table" and select "Go To Page Definition".
2. In the structure window right click on "Executables" and select "Insert inside executables -> search region".
3. Enter an ID as follows -> SrListQuery
4. Alter binding XML file so it adds these 3 attributes as shown.


<searchRegion
Binds="SrlistView1Iterator"
Criteria=""
Customizer="oracle.jbo.uicli.binding.JUSearchBindingCustomizer"
id="SrListQuery"/>

5. Switch back to the JSF page and go to the source editor and add these 3 attributes in bold to your "af:table". You must use "SrListQuery" which is the Id for the search region executable.

<af:table
value="#{bindings.SrlistView1.collectionModel}"
var="row" rows="#{bindings.SrlistView1.rangeSize}"
emptyText="#{bindings.SrlistView1.viewable ? 'No rows yet.' : 'Access Denied.'}"
fetchSize="#{bindings.SrlistView1.rangeSize}"
filterModel="#{bindings.SrListQuery.queryDescriptor}"
queryListener="#{bindings.SrListQuery.processQuery}"
selectedRowKeys="#{bindings.SrlistView1.collectionModel.selectedRow}"
selectionListener="#{bindings.SrlistView1.collectionModel.makeCurrent}"
rowSelection="single" id="table"
filterVisible="true">

Finally we need to determine which columns we wish to allow filtering to occur for which we do as follows

6. Select the "af:column" tag in the structure window.
7. Click on the + symbol to expand the "Behavior" options in the property inspector.
8. Set "Filterable" to "true".
9. Repeat steps 6 - 8 for each column you wish to be filterable.

Now when you switch to design view of your JSF page you should see your table which has a row on the top of the table which enables row filtering for the columns you enabled this for.

Wednesday, 8 April 2009

New Wait option for Sequential Redeployment in a clustered OAS 10.1.3.2 setup

When you have an application using HTTP session replication setup in a HA cluster on OAS 10.1.3.2 and above you can easily ensure that when you deploy a new version of that application it will continue to run with no down time. What's important here is you select the correct deployment option.

Redeploying with ASC

If you use ASC for the deployment then your effectively redeploying to the cluster in parallel - all nodes in cluster will get notified and process the deployment in parallel. That means you will most likey have down time and get errors for those currently using your application.

Redeploy with admin_client.jar or redeploy Ant task

With these two deployment choices you can specify sequential and keepsettings options however in some circumstances the session state of an application may be lost when you redeploy an application to a cluster.

In Oracle Containers for J2EE release 10.1.3.2 or 10.1.3.1, you can use either the waitsec parameter of the admin_client.jar -sequential waitsec subswitch or the sequentialDelay property of the redeploy Ant task to specify a number of seconds between redeployments to different OC4J instances in a cluster. This delay can provide enough time for replication of session state

For example, the following admin_client.jar command specifies a wait time of 15 seconds between redeployments to different OC4J instances:

java -jar admin_client.jar deployer:cluster:opmn://host:port/home oc4jadmin
password -redeploy -file "myapp.ear" -deploymentName rolling -sequential 15
-keepsettings
It's documented here, make sure your using 10.1.3.2 or above for this

http://download.oracle.com/docs/cd/B32110_01/relnotes.1013/b32200/oc4j.htm#CHDJJFIG
10.1.14 New Wait Option for Sequential Redeployment to a Cluster

Thursday, 2 April 2009

CYGWIN Script to copy ADF 11g JARS required for Tomcat

A work colleague told me he had to setup ADF 11g on tomcat 6.x and was lead to this link on what JAR files was required to be copied over to the %CATALINA_HOME%/lib folder.

http://blogs.oracle.com/dana/2009/01/how_to_deploy_a_11g_adf_applic_1.html

Here is a small script I wrote which will copy all those JAR files into a TEMP directory to save you time trying to find them one by one. This is a CYGWIN script as I don't know how to write BAT files.

1. Go into your JDeveloper 11g root directory as follows

papicell@papicell-au ~/d/jdev11g-boxer

2. Create a script as follows called "doCopyADF.sh"

#!/bin/sh
COPY_DIR=/cygdrive/d/temp/adf11g
export COPY_DIR;

cat adfjars.txt | while read filename
do
echo "Copying file $filename"
echo ""
find . -name "$filename" -exec cp {} $COPY_DIR \;
done


echo "All files copied.."

3. Now before you run it we need to create a list of ADF 11g JAR files it needs to find in a file called "adfjars.txt".

I simple used VI to create the list of files we need which we retrieved from the blog entry above.

adf-controller-api.jar
adf-controller-rt-common.jar
adf-controller.jar
adf-faces-databinding-rt.jar
adf-pageflow-dtrt.jar
adf-pageflow-fwk.jar
adf-pageflow-impl.jar
adf-pageflow-rc.jar
adf-richclient-api-11.jar
adf-richclient-impl-11.jar
adf-share-base.jar
adf-share-ca.jar
adf-share-support.jar
adflibfilter.jar
adflogginghandler.jar
adfm.jar
adfmweb.jar
cache.jar
commons-el.jar
db-ca.jar
dms.jar
dvt-faces.jar
dvt-jclient.jar
dvt-utils.jar
fmw_audit.jar
identitystore.jar
inspect4.jar
javatools-nodeps.jar
javax.management.j2ee_1.0.jar
jewt4.jar
jmxframework.jar
jmxspi.jar
jps-api.jar
jps-common.jar
jps-ee.jar
jps-internal.jar
jps-unsupported-api.jar
jsf-api.jar
jsf-ri.jar
jstl.jar
mdsrt.jar
ojdbc6.jar
oracle-el.jar
oraclepki.jar
org.apache.commons.beanutils_1.6.jar
org.apache.commons.collections_3.1.jar
org.apache.commons.logging_1.0.4.jar
osdt_cert.jar
osdt_core.jar
share.jar
standard.jar
trinidad-api.jar
trinidad-impl.jar
wls-api.jar
xercesImpl.jar
xmlef.jar
xmlparserv2.jar

4. Finally we need to edit the script to ensure we select a directory which exists to copy the JAR files into.

COPY_DIR=/cygdrive/d/temp/adf11g
export COPY_DIR;

5. Run as follows, ensuring you made it executable using "chmod +x doCopyADF.sh".

./doCopyADF.sh

Note: The list of required JAR files may not be 100% correct but with this script you can simple add/remove files from "adfjars.txt" to ensure you get the correct JAR files you need.

Example output.

papicell@papicell-au ~/d/jdev11g-boxer
$ ./doCopyADF.sh
Copying file adf-controller-api.jar

Copying file adf-controller-rt-common.jar

Copying file adf-controller.jar

Copying file adf-faces-databinding-rt.jar

Copying file adf-pageflow-dtrt.jar

Copying file adf-pageflow-fwk.jar

Copying file adf-pageflow-impl.jar

Copying file adf-pageflow-rc.jar

Copying file adf-richclient-api-11.jar

Copying file adf-richclient-impl-11.jar

Copying file adf-share-base.jar

Copying file adf-share-ca.jar

Copying file adf-share-support.jar

.....