Dec 28, 2013

Create RESTful Service from Java Class

With JDeveloper 12c finally it is possible to create RESTful Services from a Java Class. The implementation is based on Jersey following the Java EE 6 specification JAX-RS. For testing JDeveloper includes a comprehensive Tooling. In general RESTful services are really popular for mobile applications, e.g. ADF Mobile.


Get started
Create a simple Java Class for your business domain object plus a Service Facade that you want to expose as a RESTful Service.
package enpit.sample.adf12c.pojorest.model;

import java.util.Date;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Person {
    
    private Long id;
    private String firstname;
    private String lastname;
    private Date hiredate;    
    private Long addressId;
    
    public Person() {
        super();
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setAddressId(Long addressId) {
        this.addressId = addressId;
    }

    public Long getAddressId() {
        return addressId;
    }
}

Make sure to annotate the class with the @XmlRootElement otherwise the REST Service will not work for this domain object.
Next create a simple service facade with some test data, e.g.
package enpit.sample.adf12c.pojorest.model;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class PersonService 
{     
private List persons;    
 private Person person;    
 public PersonService()
 {        
 super();        
 this.persons = new ArrayList();       
  for (long i = 0; i < 10; i++) 
{           
  Person p = new Person();  
           p.setId(i);            
 p.setFirstname("Firstname " + i);            
 p.setLastname("Last " + i);            
 p.setHiredate(new Date());            
 this.persons.add(p);       
  }         
this.person = this.persons.get(0);    
 }
    public List getPersons()
{      
   return this.persons; 
    }
    public void addPerson(Person person) 
{     
    System.out.println("add person " + person);   
      if(person != null)
{       
      getPersons().add(person);  
       }
     }  
  public Person getPerson()
{      
   return person; 
    }
 }
So far there is nothing special. 
Create RESTful Service with the help of JDeveloper 12c
Now comes the interesting part. Select the PersonService.java in the application navigator and
choose "Create RESTful Service…"
You will get a wizard to specify the RESTful Service interface. Set the desired root path. Choose the desired media types and the Methods you want to expose as REST Service
After finishing the wizard the following happens
package enpit.sample.adf12c.pojorest.model;
import java.util.ArrayList; 
import java.util.Date;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam; 
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path("rest")
@Produces(value = { "application/json""application/xml" })
@Consumes(value = { "application/json""application/xml" }) 
public class PersonService
 {  
   private List persons;  
   private Person person;   
  public PersonService()
 {      
   super();      
   this.persons = new ArrayList()
{         
for (long i = 0; i < 10; i++)
 {       
      Person p = new Person();    
         p.setId(i);      
       p.setFirstname("Firstname " + i);    
         p.setLastname("Last " + i);     
        p.setHiredate(new Date());    
         this.persons.add(p);   
      }      
   this.person = this.persons.get(0);   
  }
    @GET   
  @Path("/persons")   
  public List getPersons()
{     
    return this.persons;     }
    @POST  
   @Path("/person")     
    public void addPerson(@FormParam("person"Person person)
 {
        System.out.println("add person " + person);    
     if(person != null)
{             getPersons().add(person);         }     } 
     @GET     
@Path("/person")  
   public Person getPerson(){  
       return person;     }
}
- web.xml is created. The Jersey Servlet is configured properly.

 

                                                                                                                                                              
Testing the RESTful Service in JDeveloper 12c
Jdeveloper is quite powerful. It lets you test the RESTful service right in the IDE.
Right-Click on the PersonService.java class and choose Run.
In background WebLogic Server 12c starts and the RESTFul Service gets deployed.
The WADL is kind of WSDL for RESTful Services. Clicking on the "Target Application WADL" URL brings you to the overview of the provided service operations.
You can test each Service Operation right from the IDE. Pressing the "Test" Button brings you to the HTTP Analyzer Screen.
Here you can choose the Method, change HTTP Headers (e.g. what kind of media type you want to accept).
Press "Send Request" to actually test the Service Operation. Make sure to change the view to "HTTP Content" not "WADL Structure" otherwise you want see the pretty formatted output on the right hand side.
Change the Accept-Header to application/json and send the request again. The output automatically will be in JSON format.
The HTTP Analyzer is even so good to parse the POST Parameter to create a good looking form for data entry

Dec 12, 2013

JSP Pre-Compilation in WebLogic Application Server:


Performance is paramount for any production system. A few seconds saved at the bottle neck is few seconds gained in the over all performance of the system. Compilation of JSP at runtime in a production environment can infuse an overhead. Hence it is a best practice to pre compile those JSP in such scenarios.
Precompilation offers below advantages:
Enhances the performance by ensuring pre compilation of all the JSPs before deployment of the application.
The Syntax errors in the sciptlet codes and custom tag elements could be detected at the compile time itself rather when the end user is accessing the application.
In WebLogic Server this can be achieved by weblogic.appc tool.
Weblogic.appc:
It’s an utility that generates and compiles the classes needed to deploy EJBs and JSP to WebLogic Application Server. It provides other features like deployment descriptor validations for standards compliance at both individual module level and the application level.
Syntax:
java weblogic.appc [options] <ear, jar, or war file or directory>

Using weblogic.appc as ant task:
You can incorporate appc in build.xml using an ant task wlappc..
For Ex:
<taskdef name="wlappc" classname="weblogic.ant.taskdefs.j2ee.Appc" classpathref="dev.classpath"/>
<target name="jspc-webapps">
<!-- Pre-compile webapp JSP pages to src/web/WEB-INF/classes -->
<wlappc source="${srcweb}" classpathref="dev.classpath" verbose="true">
</wlappc>
</target>
This would ensure that the appc would scan through the web application at the source location and precompile the JSPs.
Further references:
http://docs.oracle.com/cd/E11035_01/wls100/ejb/appc_ejbc.html

Apr 19, 2009

Sample Stateless Session Bean

Stateless session beans are session beans whose instances have no conversational state. This means that all bean instances are equivalent when they are not involved in servicing a client-invoked method. The term 'stateless' signifies that an instance has no state for a specific client.

CalculatorBean

package org.superbiz.stateless.basic;

import javax.ejb.Stateless;

@Stateless
public class CalculatorBean {

    public int add(int a, int b) {
        return a + b;
    }

    public int subtract(int a, int b) {
        return a - b;
    }

    public int multiply(int a, int b) {
        return a * b;
    }

    public int divide(int a, int b) {
        return a / b;
    }

    public int remainder(int a, int b) {
        return a % b;
    }
}

CalculatorTest

Our CalculatorBean can be easily tested using the EJBContainer API in EJB 3.1
package org.superbiz.stateless.basic;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import javax.ejb.embeddable.EJBContainer;
import javax.naming.NamingException;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class CalculatorTest {

    private static EJBContainer ejbContainer;

    private CalculatorBean calculator;

    @BeforeClass
    public static void startTheContainer() {
        ejbContainer = EJBContainer.createEJBContainer();
    }

    @Before
    public void lookupABean() throws NamingException {
        Object object = ejbContainer.getContext().lookup("java:global/simple-stateless/CalculatorBean");

        assertTrue(object instanceof CalculatorBean);

        calculator = (CalculatorBean) object;
    }

    @AfterClass
    public static void stopTheContainer() {
        if (ejbContainer != null) {
            ejbContainer.close();
        }
    }

    /**
     * Test Add method
     */
    @Test
    public void testAdd() {

        assertEquals(10, calculator.add(4, 6));

    }

    /**
     * Test Subtract method
     */
    @Test
    public void testSubtract() {

        assertEquals(-2, calculator.subtract(4, 6));

    }

    /**
     * Test Multiply method
     */
    @Test
    public void testMultiply() {

        assertEquals(24, calculator.multiply(4, 6));

    }

    /**
     * Test Divide method
     */
    @Test
    public void testDivide() {

        assertEquals(2, calculator.divide(12, 6));

    }

    /**
     * Test Remainder method
     */
    @Test
    public void testRemainder() {

        assertEquals(4, calculator.remainder(46, 6));

    }

}

Aug 22, 2008

Simple REST(Jax- RS) Example

Defining a REST service is pretty easy, simply ad @Path annotation to a class then define on methods the HTTP method to use (@GET, @POST, ...).

Here we see a bean that uses the Bean-Managed Concurrency option as well as the @Startup annotation which causes the bean to be instantiated by the container when the application starts. Singleton beans with @ConcurrencyManagement(BEAN) are responsible for their own thread-safety. The bean shown is a simple properties "registry" and provides a place where options could be set and retrieved by all beans in the application.

package org.superbiz.rest;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;

@Path("/greeting")
public class GreetingService {
    @GET
    public String message() {
        return "Hi REST!";
    }

    @POST
    public String lowerCase(final String message) {
        return "Hi REST!".toLowerCase();
    }
}

Testing

Test for the JAXRS service

The test uses the OpenEJB ApplicationComposer to make it trivial.
The idea is first to activate the jaxrs services. This is done using @EnableServices annotation.
Then we create on the fly the application simply returning an object representing the web.xml. Here we simply use it to define the context root but you can use it to define your REST Application too. And to complete the application definition we add @Classes annotation to define the set of classes to use in this app.
Finally to test it we use cxf client API to call the REST service in get() and post() methods.
package org.superbiz.rest;

import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.openejb.jee.SingletonBean;
import org.apache.openejb.junit.ApplicationComposer;
import org.apache.openejb.junit.EnableServices;
import org.apache.openejb.junit.Module;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.IOException;

import static org.junit.Assert.assertEquals;

@EnableServices(value = "jaxrs")
@RunWith(ApplicationComposer.class)
public class GreetingServiceTest {
    @Module
    public SingletonBean app() {
        return (SingletonBean) new SingletonBean(GreetingService.class).localBean();
    }

    @Test
    public void get() throws IOException {
        final String message = WebClient.create("http://localhost:4204").path("/GreetingServiceTest/greeting/").get(String.class);
        assertEquals("Hi REST!", message);
    }

    @Test
    public void post() throws IOException {
        final String message = WebClient.create("http://localhost:4204").path("/GreetingServiceTest/greeting/").post("Hi REST!", String.class);
        assertEquals("hi rest!", message);
    }
}

Running

Running the example is fairly simple. In the "simple-rest" directory run:
$ mvn clean install

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.004 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

APIs Used

  • javax.ws.rs.GET
  • javax.ws.rs.POST
  • javax.ws.rs.Path

Apr 12, 2008

Writing a Java Concurrent Program

Steps in writing Java Concurrent Program

Template Program:

Copy the template Java Concurrent Program from $FND_TOP/java/cp/request/Template.java to your directory and start coding according to your requirement. Change file name and class name to your required name as Java Concurrent Program name.
================= Template.java===========================
package oracle.apps.fnd.cp.request;
// Change the package name to the required one.
// import all the other required classes/packages.
import oracle.apps.fnd.util.*;
import oracle.apps.fnd.cp.request.*;
// Change the name of the class from Template to your
// concurrent program class name
public class Template implements JavaConcurrentProgram
{
   /** Optionally provide class constructor without any arguments.
    *  If you provide any arguments to the class constructor then while
    *  running the program will fail.
    */
   public void runProgram(CpContext pCpContext)
   {
        ReqCompletion lRC = pCpContext.getReqCompletion();
        String CompletionText = "";
        /* Code your program logic here.
         * Use getJDBCConnection method to get the connection
* object for any JDBC operations.
         * Use CpContext provided commit,rollback methods to
* commit/rollback data base transactions.
         * Don't forget to release the connection before returning
* from this method.
         */
        /* Call setCompletion method to set the request completion
* status and completion text.
         * Status values are ReqCompletion.NORMAL,ReqCompletion.WARNING,
         * ReqCompletion.ERROR.
         * Use Completion text message of length 240 characters.
* If it is more than 240 then full string will appear in
* log file and truncated 240 characters will be used as
* request completion text.
         */
         lRC.setCompletion(ReqCompletion.NORMAL, CompletionText);
    }
}
==================End of Template.java===========================

program Logic


Implement the runProgram with your Java Concurrent Program business logic. runProgram() gets the CpContext .  CpContext is a subclass of AOL/J AppsContext which provides the request specific member classes LogFile to write to request log file, OutFile to write to request output file and ReqCompletion to set the completion status of the request. 
Program Parameters 
CpContext uses the AOL/J utility Parameter List to pass the parameters to the Java Concurrent Program.
Please refer AOL/J Parameter list to get the Parameter List name, value pairs. You will be referring parameter list name as the parameter name and corresponding value as the parameter value in the Java Concurrent Program. You have to register the parameter names as token name in the register concurrent program form Parameter screen. 

Database Operations 
Use getJDBCConnection method to get the connection object for any JDBC operations within program and release the connection to the AppsContext connection pool. Use CpContext's commit(), rollback() methods to commit or rollback the transactions in the database. These methods will set the program proffered rollback segments after commit or rollback segments for the rest of the database transaction in the Java Concurrent Program. 
Setting request Completion Status 
Call setCompletion() method of the ReqCompletion object which is a member of CpContext before returning from your Java Concurrent Program to set the completion status for the program and optional completion text. 

Register executable

Register your Java Concurrent Program class name as execution_file_name and package name in execution_file_path in register concurrent executables form

Register Concurrent Program

Register you Java Concurrent Program as concurrent program in the register concurrent program form. Register all the parameters that you want to pass to the program in the parameter screen of this form. Register the Parameter List names referred in the program as the token names in the parameter screen.

Test Program from OS Prompt

You can test your Java Concurrent Program from OS prompt by using the following syntax: 

jre -Ddbcfile= 
            [ -Drequest.logfile=
            [ -Drequest.requestid=
            [ -Drequest.outfile=
            [ -Drequest.userid=  ] 
            [ -Drequest.respapplid=
            [ -Drequest.respid=
            [ -Drequest.secgrpid=
            [ -Drequest.enabletrace=
            oracle.apps.fnd.cp.request.Run  
            [

     Example: 
     jre -Ddbcfile=/d2/fnd/secure/appsnode_appdb.dbc 
          -Dreqeust.requestid=23453 -Drequest.logfile=./myreq.log 
           oracle.apps.fnd.cp.request.Run oracle.apps.wip.program.MyProg 
           "TOKEN1=value1:TOKEN2=value2"
If you don't specify the 'request.logfile' with -D option then the all the log file information will be printed to the standard output. Specify the 'request.requestid' to rerun already completed request. You can specify the all the application user specific context values with -D to get the specific user context to the program when run from the OS prompt. Pass all the parameters if any by using the AOL/J Parameter list syntax.

Sample Program

package oracle.apps.fnd.cp.request;
import java.io.*;
import java.sql.*;
import oracle.apps.fnd.util.*;
public class AvailableProg implements JavaConcurrentProgram
{
   String applName;
   public AvailableProg()
   {
        // if no parameter value is specified for
// APPLNAME then use FND as default value
        applName = "FND";
   }
   public void runProgram(CpContext pCpContext)
   {
        // get the JDBC connection object
        Connection mJConn = pCpContext.getJDBCConnection();
        // get parameter list object from CpContext
        ParameterList lPara = pCpContext.getParameterList();
        // get ReqCompletion object from CpContext
        ReqCompletion lRC = pCpContext.getReqCompletion();
        String lQuery =
                " select substr(user_concurrent_program_name,1,70) , " +
                " decode(enabled_flag,'Y','Enabled','N','Disabled') " +
                " from fnd_concurrent_programs_vl cp, fnd_application_vl a " +
                " where cp.application_id        = a.application_id " +
                " and a.application_short_name = ? " +
                " order by 1 " ;
        // check for the APPLNAME parameter token name and if it there get
        // value and use it as the application short name in the query
        while (lPara.hasMoreElements())
        {
                NameValueType aNVT = lPara.nextParameter();
                if ( aNVT.getName().equals("APPLNAME") )
                        applName = aNVT.getValue();
        }
        try
        {
           PreparedStatement lStmt = mJConn.prepareStatement(lQuery);
           lStmt.setString(1, applName );
           ResultSet lRs = lStmt.executeQuery();
           // get OutFile object from CpContext
           OutFile lOF = pCpContext.getOutFile();
           // get LogFile object from CpContext
           LogFile lLF = pCpContext.getLogFile();
           lLF.writeln("Generating Programs for Application : "  + applName,
                      LogFile.STATEMENT);
           lOF.writeln(
           "                Available Concurrent Programs for Application " +
                         applName );
           lOF.writeln(
           "Concurrent Program Name                             Enabled");
          lOF.writeln(
           "----------------------------------------------" );
         while( lRs.next() )
           {
                lOF.writeln(lRs.getString(1) + "   " + lRs.getString(2) );
           }
           lLF.writeln("Generated Programs for Application : " + applName,
                     LogFile.STATEMENT);
           lStmt.close();
           lRC.setCompletion(ReqCompletion.NORMAL, "Request Completed Normal");
        }
        catch (SQLException e)
        {
              lRC.setCompletion(ReqCompletion.ERROR, e.toString());
        }
        finally
        {
pCpContext.releaseJDBCConnection();
    }
    }
}
NOTE: If you're creating a BC4J Application Module in a concurrent program and are passing CpContext object to it, you should NOT call releaseJDBCConnection() on CpContext while it is still in use by the BC4J AM. You should clean up after the AM properly by calling am.remove().