Oracle® Fusion Middleware Developer's Guide for Oracle Enterprise Scheduling Service 11g Release 1 (11.1.1.6.0) Part Number E24713-01 |
|
|
PDF · Mobi · ePub |
This chapter describes how to create and run an application that uses Oracle Enterprise Scheduling Service to run job requests and demonstrates how to work with Oracle JDeveloper to create an application using Oracle Enterprise Scheduling Service.
Note:
This chapter includes a tutorial that uses an older release of Oracle JDeveloper. This content is deprecated. For development with a current version of Oracle JDeveloper, see Chapter 4, "Using Oracle JDeveloper to Generate an Oracle Enterprise Scheduling Service Application".The chapter then shows a variation on the sample application using two split applications — a job submission application, a submitter, and a job execution application, a hosting application.
This chapter includes the following sections:
Section 5.1, "Introduction to the Oracle Enterprise Scheduling Service Sample Application"
Section 5.2, "Creating the Application and Projects for the Sample Application"
Section 5.3, "Creating a Java Implementation Class for the Sample Application"
Section 5.4, "Adding Application Code to Submit Oracle Enterprise Scheduling Service Job Requests"
Section 5.5, "Creating Metadata for Oracle Enterprise Scheduling Service Sample Application"
Section 5.6, "Assembling the Oracle Enterprise Scheduling Service Sample Application"
Section 5.7, "Deploying and Running the Oracle Enterprise Scheduling Service Sample Application"
Section 5.8, "Troubleshooting the Oracle Enterprise Scheduling Service Sample Application"
Section 5.9, "Using Submitting and Hosting Split Applications"
The Oracle Enterprise Scheduling Service sample application includes a complete application that you build with Oracle JDeveloper using Oracle Enterprise Scheduling Service APIs. Oracle Enterprise Scheduling Service lets you run different types of job requests, including: Java classes, PL/SQL procedures, and process type jobs. To create an application that schedules job requests you need to do the following:
Create the Java classes, PL/SQL procedures, or executable processes that specify the routine you want to schedule and run with Oracle Enterprise Scheduling Service.
Specify Oracle Enterprise Scheduling Service metadata and the characteristics for job requests.
Define the Java application that uses Oracle Enterprise Scheduling Service APIs to specify and submit job requests.
Assemble and deploy the Java application that uses Oracle Enterprise Scheduling Service APIs.
Run the Java application that uses Oracle Enterprise Scheduling Service APIs.
Note:
The instructions in this chapter assume that you are using a new Oracle JDeveloper that you install without previously saved projects or other saved Oracle JDeveloper state. If you have previously used Oracle JDeveloper, some of the instructions may not match the exact steps shown in this chapter, or you may be able to shorten procedures or perform the same action in fewer steps. In some cases Oracle JDeveloper does not show certain dialogs based on your past use of Oracle JDeveloper.When you use Oracle Enterprise Scheduling Service the application Metadata is stored with MDS. To use MDS you need to have access to a database with MDS user and schema configured.
Using Oracle JDeveloper you create an application and the projects within the application contain the code and support files for the application. To create the sample application you need to do the following:
Create an application in Oracle JDeveloper.
Create a project in Oracle JDeveloper.
Create the application code that uses the Oracle Enterprise Scheduling Service APIs. For the sample application you create the EssDemo servlet in the EssDemoApp application.
Note:
This chapter includes a tutorial that uses an older release of Oracle JDeveloper. This content is deprecated. For development with a current version of Oracle JDeveloper, see Chapter 4, "Using Oracle JDeveloper to Generate an Oracle Enterprise Scheduling Service Application".To work with Oracle Enterprise Scheduling Service, you first create an application and a project in Oracle JDeveloper.
To create the EssDemo application:
In the Application Navigator, select New Application....
In the Name your application window enter the name and location for the new application.
In the Application Name field, enter an application name. For this sample application, enter EssDemoApp
.
In the Directory field, accept the default.
Enter an application package prefix or accept the default, no prefix.
The prefix, followed by a period, applies to objects created in the initial project of an application.
In the Application Template area, select Fusion Web Application (ADF).
Click Next.
Click Finish.
This displays the File Summary page, as shown in Figure 5-1.
When you create an application using the Fusion Web Application (ADF) template, Oracle JDeveloper adds two projects in the application named Model and ViewController (Oracle ADF is based on the MVC design pattern that includes these areas). To organize an Oracle Enterprise Scheduling Service application you add another project and use this project to add the Oracle Enterprise Scheduling Service metadata and the Oracle Enterprise Scheduling Service implementation for the Java classes that you want to run with Oracle Enterprise Scheduling Service.
To create a project:
From the Application Menu for the EssDemoApp application select New Project....
In the New Gallery, under Categories expand General and select Projects.
In the Items area select ADF Model Project, as shown in Figure 5-2.
Click OK.
On the Name Your Project page enter a project name. For example, enter EssDemo
as the project name, as shown in Figure 5-3.
Click Finish.
Configure Oracle JDeveloper resource options for project:
In the Application Navigator, select the EssDemo project.
Right-click and from the dropdown list select Project Properties....
In the Project Properties window, in the navigator expand Project Source Paths and select Resources.
Select the Included tab and then select the Include Content From Subfolders check box, as shown in Figure 5-4.
Click OK.
You need to add the Oracle Enterprise Scheduling Service extensions to the project before you use the Oracle Enterprise Scheduling Service APIs.
To allow Oracle JDeveloper to use Oracle Enterprise Scheduling Service extensions:
In Oracle JDeveloper, in the Application Navigator select the EssDemo project.
Right-click and from the dropdown list select Project Properties....
In the Project Properties navigator, select Libraries and Classpath.
In the Libraries and Classpath area, click Add Library....
In the Add Library dialog, in the Libraries area select Enterprise Scheduler Extensions.
In the Add Library dialog click OK. This adds the appropriate libraries, as shown in Figure 5-5.
Click OK to dismiss the Project Properties dialog.
To define an application that runs a Java class under control of Oracle Enterprise Scheduling Service you need to create the Java class that implements the Oracle Enterprise Scheduling Service Executable
interface. The Executable
interface specifies the contract that allows you to use Oracle Enterprise Scheduling Service to invoke a Java class.
A Java class that implements the Executable
interface must provide an empty execute()
method.
To create a Java class that implements the executable interface:
In the Application Navigator, select the EssDemo project.
In the Overview area, select the Java Class navigation tab as shown in Figure 5-6.
In the Overview area in the Java Files area, select New and from the dropdown list select Java Class.
In the Select a Project dialog, select the EssDemo.jpr project.
Click OK. This displays the Create Java Class dialog.
In the Create Java Class dialog, in the Name field, enter HelloWorld
.
In the Create Java Class window, in the Package field, enter essdemo
.
In other fields accept the defaults as shown in Figure 5-7.
Click OK.
Replace the generated contents of the HelloWorld.java
file with the contents of the HelloWorld.java
supplied with the sample, as shown in Example 5-1. This code is also shown in Figure 5-8.
Example 5-1 shows HelloWorld()
, the Java class that implements the interface oracle.as.scheduler.Executable
.
Example 5-1 Oracle Enterprise Scheduling Service HelloWorld Java Class
package essdemo; import oracle.as.scheduler.RequestParameters; import oracle.as.scheduler.Executable; import oracle.as.scheduler.ExecutionCancelledException; import oracle.as.scheduler.ExecutionErrorException; import oracle.as.scheduler.ExecutionPausedException; import oracle.as.scheduler.ExecutionWarningException; import oracle.as.scheduler.RequestExecutionContext; public class HelloWorld implements Executable { public HelloWorld() { } public void execute(RequestExecutionContext ctx, RequestParameters params) throws ExecutionErrorException, ExecutionWarningException, ExecutionCancelledException, ExecutionPausedException { System.out.println("**** Sample Job Running, Request ID: " + ctx.getRequestId()); } }
You need to create a Java class to use Oracle Enterprise Scheduling Service. The Oracle Enterprise Scheduling Service Executable
interface provides a hook for using the Java class that you supply with Oracle Enterprise Scheduling Service. A Java class that implements the Executable
interface can be submitted to Oracle Enterprise Scheduling Service for execution.
When you create a class that implements the Executable
interface you should follow certain practices to make sure that your code performs correctly. These practices allow you to handle Oracle Enterprise Scheduling Service exceptions.
Note:
Every time a job request executes, Oracle Enterprise Scheduling Service calls theexecute()
method. All of the business logic associated with a job request should be implemented through this method. Thus, the Java implementation should not rely on instance or static member variables for maintaining state. The Java implementation can use static variables but their use is not recommended to manage state.In Example 5-1, note the following:
The routine should throw the ExecutionErrorException
to signal to the Oracle Enterprise Scheduling Service runtime that an unrecoverable error occurred during execution. For example, you can wrap your exception generated during execution with this exception. Upon this exception, Oracle Enterprise Scheduling Service transitions the request to the ERROR
state.The routine should throw the ExecutionWarningException
when the implementation detects a failure condition that it needs to communicate to Oracle Enterprise Scheduling Service. Upon this exception, Oracle Enterprise Scheduling Service transitions the request to the WARNING
state. The routine should throw the ExecutionCancelledException
when the implementation detects a condition for request cancellation that it needs to communicate to Oracle Enterprise Scheduling Service. Upon this exception, Oracle Enterprise Scheduling Service transitions the request to the CANCELLED
state.
The routine should throw the ExecutionPausedException
to indicate that the class implementing the Executable interface should pause for the completion of a subrequest. Upon this exception, Oracle Enterprise Scheduling Service transitions the request to the PAUSED
state.
In an Oracle Enterprise Scheduling Service application you use the Oracle Enterprise Scheduling Service APIs to submit job requests from any component in the application. The EssDemoApp
sample application provides a Java servlet for a servlet based user interface for submitting job requests (using Oracle Enterprise Scheduling Service).
You need to add the EJB3.0 libraries and the Oracle Enterprise Scheduling Service extensions to the ViewController project before you use the Oracle Enterprise Scheduling Service APIs in a servlet.
To add Oracle JDeveloper EJB3.0 and Oracle Enterprise Scheduling Service libraries:
In the Application Navigator select the ViewController project.
Right-click and from the dropdown list select Project Properties....
In the Project Properties navigator, select Libraries and Classpath.
In the Libraries and Classpath area, click Add Library....
In the Add Library dialog select Enterprise Scheduler Extensions.
In the Add Library dialog also select EJB 3.0.
Click OK. This action adds the libraries as shown in Figure 5-9.
Click OK to dismiss the Project Properties dialog.
Using MVC design pattern you create the EssDemo servlet in the ViewController project.
To create the sample servlet:
In Application Navigator select the ViewController project.
Click the New... icon to open the New Gallery.
In the New Gallery, in the Categories area expand Web Tier and select Servlets.
In the New Gallery, in the Items area select HTTP Servlet.
Click OK. This starts the Create HTTP Servlet Wizard.
On the create HTTP Servlet Page - Welcome, click Next.
On the Create HTTP Servlet - Step 1 of 3: Servlet Information page, enter the class name in the Class field. For this example in the Class field, enter EssDemo.
Enter the package name in the Package field. For this example, in the Package field, enter demo.
In the Generate Content Type field, from the dropdown list select HTML.
In the Implement Methods area, select the doGet() and doPost() check boxes, as shown in Figure 5-10.
Click Next.
In the Create HTTP Servlet - Step 2 of 3: Mapping Information dialog, in the Name field, enter: EssDemo
In the Create HTTP Servlet - Step 2 of 3: Mapping Information dialog, in the URL Pattern field, enter: /essdemo/*
, as shown in Figure 5-11.
Click Finish.
The supplied EssDemo application includes the completed servlet. You need to copy the source code into your project. To do this, in Oracle JDeveloper replace the contents of the servlet with the contents of the file EssDemo.java
supplied with the sample application, as shown in Figure 5-12. The EssDemo.java
sample code includes several hundred lines, so it is not included in this text in an example.
To use the Oracle Enterprise Scheduling Service sample application to submit a job request you need to create metadata that defines a job request, including the following:
A job type: this specifies an execution type and defines a common set of parameters for a job request.
A job definition: this is the basic unit of work that defines a job request in Oracle Enterprise Scheduling Service.
An Oracle Enterprise Scheduling Service job type specifies an execution type and defines a common set of parameters for a job request.
To create a job type:
In the Application Navigator, select the EssDemo project.
Press Ctrl-N. This displays the New Gallery.
In the New Gallery, select the All Technologies tab.
In the New Gallery, in the Categories area expand Business Tier and select Enterprise Scheduler Metadata.
In the New Gallery, in the Items area select Job Type as shown in Figure 5-13.
Click OK. This displays the Create Job Type dialog.
In the Create Job Type dialog, specify the following:
In the Name field, enter a name for the job type. For this example, enter the name: Jobtype_essdemo1
.
In the Package field, enter a package name. For example, enter mypackage
.
In the Execution Type field, from the dropdown list select JAVA_TYPE as shown in Figure 5-14.
Click OK. This creates the Jobtype_essdemo1.xml
file and Oracle JDeveloper displays the Job Type page.
In the Job Type page, in the Description field enter a description for the job type. For this example enter: Sample Java Job Type
.
In the Class Name field, click the Browse icon.
Click the Hierarchy tab and then navigate to select the appropriate class. For this sample application, select essdemo.HelloWorld. Click OK.
The Job Type page displays, as shown in Figure 5-15.
Tip:
You can add the job class at either the job type level or the job definition level.To use a Java class with Oracle Enterprise Scheduling Service you need to create a job definition. A job definition is the basic unit of work that defines a job request in Oracle Enterprise Scheduling Service.
When you create a job definition you specify a name, select a job type, and specify system properties.
To create a job definition:
In the Application Navigator, select the EssDemo project.
Press Ctrl-N. This displays the New Gallery.
In the New Gallery in the Categories area expand Business Tier and select Enterprise Scheduler Metadata.
In the New Gallery in the Items area select Job Definition.
Click OK. Oracle JDeveloper displays the Create Job Definition dialog.
Use the Create Job Definition dialog to specify the following:
Enter a name for the job definition or accept the default name. For example, for the sample application, enter Job_essdemo1.
In the Package field, enter a package name. For example, enter mypackage
.
In the JobType field, from the dropdown list select a value. For example for the sample application select the job type you previously created, Jobtype_essdemo1, as shown in Figure 5-16.
Click OK. This creates the job definition Job_essdemo1.xml
and the jobs folder in mypackage and shows the Job Definition page, as shown in Figure 5-17.
In the System Properties field, click the add button and create a system property called EffectiveApplication
. Set its value to that used in Section 5.6.1, "How to Assemble the EJB Jar Files for Oracle Enterprise Scheduling Service Sample Application."
After you create the sample application you use Oracle JDeveloper to assemble the application.
To assemble the application you do the following:
Create the EJB Jar files
Create the application MAR File
Create the application EAR file
Update WAR File options
The sample application needs to contain the required EJB descriptors. You need to create the ejb-jar.xml
and weblogic-ejb-jar.xml
files and include these files with any Java implementation class that you create.
Oracle Enterprise Scheduling Service requires an application to assemble and provide an EJB JAR so that Oracle Enterprise Scheduling Service can find its entry point in the application while running job requests on behalf of the application. This EJB jar should have its required EJB descriptors in ejb-jar.xml
and weblogic-ejb-jar
, as well as any Java class implementations that are going to be submitted to Oracle Enterprise Scheduling Service. The descriptor files ejb-jar.xml
and weblogic-ejb-jar
must contain descriptions for the Oracle Enterprise Scheduling Service EJBs and should not be modified.
To prepare for the assembly of the sample application, do the following to add the EJB jar files:
Create the ejb-jar.xml
file: this provides the description for the Oracle Enterprise Scheduling Service EJBs and associated resources. The context of Oracle Enterprise Scheduling Service request submission, processing, metadata, and runtime data for an application is specified as the name of an Oracle Enterprise Scheduling Service client application using the deployment name. You can also specify the context using the applicationName
property, as shown in Example 5-4.
Create the weblogic-ejb-jar.xml
file: this provides the Oracle WebLogic Server specific descriptions for the Oracle Enterprise Scheduling Service EJBs and associated resources.
Create the EJB JAR archive: this includes descriptors for the Java Job implementations.
To create the ejb-jar.xml file in the Java implementation project:
In Application Navigator select the EssDemo project.
Click the New... icon.
In the New Gallery, in the navigator expand General and select Deployment Descriptors.
In the New Gallery in the Items area select Java EE Deployment Descriptor.
Click OK.
In the Select Descriptor page select ejb-jar.xml.
Click Next.
In the Select Version page select 3.0.
Click Finish.
This creates ejb-jar.xml
file and the META-INF
directory in the EssDemo project, as shown in Figure 5-18.
Replace the entire contents of the ejb-jar.xml
file that you just created with a copy of the ejb-jar.xml
supplied with the sample application. This sample ejb-jar.xml
file is shown in Example 5-2.
Example 5-2 EJB Contents to Copy to ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?> <ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0"> <display-name>ESS</display-name> <enterprise-beans> <message-driven> <ejb-name>ESSAppEndpoint</ejb-name> <ejb-class>oracle.as.scheduler.ejb.EssAppEndpointBean</ejb-class> </message-driven> <session> <description>Async Request Bean</description> <ejb-name>AsyncRequestBean</ejb-name> <ejb-class>oracle.as.scheduler.ejb.AsyncRequestBean</ejb-class> </session> <session> <description>Runtime Session Bean</description> <ejb-name>RuntimeServiceBean</ejb-name> <ejb-class>oracle.as.scheduler.ejb.RuntimeServiceBean</ejb-class> </session> <session> <description>Metadata Session Bean</description> <ejb-name>MetadataServiceBean</ejb-name> <ejb-class>oracle.as.scheduler.ejb.MetadataServiceBean</ejb-class> </session> </enterprise-beans>
To create the weblogic-ejb-jar.xml file in the Java implementation project:
In Application Navigator select the EssDemo project.
Click New... icon.
Under Categories expand General and select Deployment Descriptors.
In the Items area select Weblogic Deployment Descriptor.
Click OK.
In the Select Descriptor dialog, select weblogic-ejb-jar.xml.
Click Next.
Click Next.
Click Finish. This creates weblogic-ejb-jar.xml
file.
Replace the entire contents of the weblogic-ejb-jar.xml
file with the sample weblogic-ejb-jar.xml
supplied with the sample application. This file is shown in Example 5-3.
Example 5-3 EJB Descriptor Contents to Copy to weblogic-ejb-jar.xml File
<?xml version="1.0" encoding="US-ASCII" ?> <weblogic-ejb-jar xmlns="http://www.bea.com/ns/weblogic/10.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/10.0 http://www.bea.com/ns/weblogic/10.0/weblogic-ejb-jar.xsd"> <weblogic-enterprise-bean> <ejb-name>ESSAppEndpoint</ejb-name> <message-driven-descriptor> <resource-adapter-jndi-name>ess/ra</resource-adapter-jndi-name> </message-driven-descriptor> <dispatch-policy>ESSRAWM</dispatch-policy> </weblogic-enterprise-bean> <run-as-role-assignment> <role-name>essSystemRole</role-name> <run-as-principal-name>weblogic</run-as-principal-name> </run-as-role-assignment> </weblogic-ejb-jar>
To create the EJB JAR archive:
In Application Navigator select the EssDemo project.
Right-click and from the dropdown list, select Make EssDemo.jpr. In the Messages Log you should see a successful compilation message, for example:
[3:40:22 PM] Successful compilation: 0 errors, 0 warnings.
In Application Navigator select the EssDemo project.
Select the New... icon.
In the New Gallery, in the Categories area expand General and select Deployment Profiles.
In the New Gallery, in the Items area select EJB JAR File.
Click OK. This displays the Create Deployment Profile - EJB JAR File dialog.
In the Create Deployment Profile - EJB JAR File dialog, in the Deployment Profile Name field enter ess-ejb
.
Click OK. This displays the Edit EJB JAR Deployment Profile Properties dialog.
In the Edit EJB JAR Deployment Profile Properties dialog, in the Enterprise Application Name field enter EssDemoApp
, as shown in Figure 5-19.
In the EJB JAR Deployment Profile Properties dialog, in the Navigator expand File Groups and expand Project Output, and select Contributors.
In the Contributors area select Project Output Directory and Project Dependencies as shown in Figure 5-20.
In the EJB JAR Deployment Properties dialog, in the Navigator expand File Groups and Project Output, and select Filters.
Select the META-INF folder and the essdemo folder as shown in Figure 5-21.
On the EJB JAR Deployment Profile Properties page, click OK.
On the Project Properties page, click OK.
To update WAR archive options:
In the Application Navigator, select the ViewController project.
Right-click and select Project Properties....
In the Navigator, select Deployment.
In the Deployment page, in the Deployment Profiles area select the WAR File.
Click Edit.... This displays the Edit WAR Deployment Profile Properties dialog.
In the Edit War Deployment Profile Properties dialog, select General and configure the General page as follows, as shown in Figure 5-22:
Set the WAR File: path_to_mywork
/mywork/EssDemoApp/ViewController/deploy/EssDemoApp_ViewController_webapp1.war
In the Web Application Context Root area, select Specify Java EE Web Context Root:
In the Specify Java EE Web Context Root: text entry area, enter EssDemoApp
.
In the Deployment Client Maximum Heap Size (in Megabytes): dropdown list select Auto
In the Edit WAR Deployment Profile Properties dialog, click OK.
Oracle JDeveloper updates the deployment profile.
In the Project Properties dialog, click OK.
An application either uses the deployment name as the default value for its application name or you can set the application name using the property applicationName
in the ejb-jar.xml
. The default application name is the deployment name if the applicationName
is not specified.
To set the applicationName
edit the ejb-jar.xml
file to set the value of the <activation-config-property>
named applicationName
, as shown in Example 5-4.
Example 5-4 Setting applicationName in ejb-jar.xml
<enterprise-beans>
<message-driven>
<ejb-name>ESSAppEndpoint</ejb-name>
<ejb-class>oracle.as.scheduler.ejb.EssAppEndpointBean</ejb-class>
<activation-config>
<activation-config-property>
<activation-config-property-name>
applicationName
</activation-config-property-name>
<activation-config-property-value>
MY_APPLICATION_NAME
</activation-config-property-value>
</activation-config-property>
</activation-config>
</message-driven>
<enterprise-beans>
The sample application needs to contain the required MAR profile.
To create the MAR file:
Open the EssDemoApp application and from the Application Menu select Application Properties...
In the Application Properties dialog, in the navigator select Deployment.
Select and delete the default deployment profile.
Click New.... This displays the Create Deployment Profile page.
In the Archive Type field, from the dropdown list select MAR File as shown in Figure 5-23.
In the Create Deployment Profile dialog, in the Name field enter a name, for example enter essMAR.
In the Create Deployment Profile dialog, click OK.
On the Edit MAR Deployment Profile dialog, in the navigator expand Metadata File Groups and select User Metadata.
Click Add.... This displays the Add Contributor dialog.
On the Add Contributor dialog click Browse to add the essmeta metadata that contains the namespace for the Jobs and JobTypes directory, as shown in Figure 5-24. Note, you select the path that you need to include in the Add Contributor dialog by double-clicking the essmeta directory.
On the Add Contributor dialog, click OK.
In the navigator expand Metadata File Groups and User Metadata and select Directories.
Select the mypackage
directory. This selects all the appropriate information for Oracle Enterprise Scheduling Service application user metadata for the application.
Select the bottom most directory in the tree. This is the directory from which the namespace is created. For example, when selecting oracle
, the namespace is oracle
. When selecting the product
directory, the namespace is oracle/apps/product
. For example, to create the namespace oracle/apps/product/component/ess
, click the ess
directory.
The folder you select in this dialog determines the top level namespace in adf-config.xml
. For more information, see Section 5.6.3, "How to Assemble the EAR File for Oracle Enterprise Scheduling Service Sample Application." This namespace should be the same as the package defined in job and job type definition. For more information, see Section 5.5, "Creating Metadata for Oracle Enterprise Scheduling Service Sample Application."
Note:
If your namespace is too generic, then your Oracle ADF application might fail. Make sure to use proper package structure and map only the required namespaces.On the Edit MAR Deployment Profile Properties page, click OK.
On the Application Properties page, in the navigator expand Run and select MDS.
Select the MAR profile you just created, essMAR, as shown in Figure 5-25.
Click OK.
You need to prepare an EAR file that assembles the sample application. The EAR archive consists of the following:
EJB JAR including the Oracle Enterprise Scheduling Service Java job implementation.
WAR archive with the EssDemo servlet.
To create the EAR file for the application:
In the Application Navigator, select the EssDemoApp application.
From the Application Menu, select Application Properties....
In the Application Properties Navigator, select Deployment.
Click New... to create a new deployment descriptor.
In the Archive Type dropdown list, select EAR File.
In the Create Deployment Profile dialog in the Name field enter the application name. For the application, enter EssDemoApp
.
Click OK.
In the Edit EAR Deployment Profile Properties dialog, in the navigator select Application Assembly.
In the Application Assembly page in the Java EE Modules area select the appropriate check boxes, including the following: essMAR, the WEB module in the ViewController project and the EJB module, ess-ejb, in the EssDemo project as shown in Figure 5-26.
Click OK.
On the Application Properties page, click OK.
You need to update the weblogic-application.xml
file to include the oracle.ess
library.
In the Application Navigator expand Application Resources.
In the navigator expand Descriptors and expand META-INF, as shown in Figure 5-27.
Double-click to open the weblogic-application.xml
file.
Add the following to the weblogic-application.xml
file. Example 5-5 shows a complete weblogic-application.xml
file, including this <library-ref>
element.
<library-ref> <library-name>oracle.ess</library-name> </library-ref>
Example 5-5 Contents of Sample weblogic-application.xml File with oracle.ess
<?xml version = '1.0' encoding = 'UTF-8'?> <weblogic-application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-application http://www.bea.com/ns/weblogic/weblogic-application/1.0/weblogic-application.xsd" xmlns="http://www.bea.com/ns/weblogic/weblogic-application"> <listener> <listener-class>oracle.mds.lcm.weblogic.WLLifecycleListener</listener-class> </listener> <listener> <listener-class>oracle.adf.share.weblogic.listeners.ADFApplicationLifecycleListener</listener-class> </listener> <library-ref> <library-name>adf.oracle.domain</library-name> <implementation-version>11.1.1.1.0</implementation-version> </library-ref> <library-ref> <library-name>oracle.ess</library-name> </library-ref> </weblogic-application>
After you complete the steps to build and assemble the sample application you need to deploy the application to Oracle WebLogic Server. After you successfully deploy an application you can run the application. For the sample application you use a browser to run the EssDemo servlet to submit job requests to Oracle Enterprise Scheduling Service running on Oracle WebLogic Server.
To deploy the EssDemoApp application you need a properly configured and running Oracle WebLogic Server, and you need an active metadata server. When you deploy the application Oracle JDeveloper brings up the Deployment Configuration page. Select your repository from the dropdown list and Enter a partition name (the partition name defaults to application name).
To deploy the EssDemoApp application:
Check the Run Manager to make sure the Oracle WebLogic Server is up and running. If the Oracle WebLogic Server is not running, start the server. To start the server, from the Run menu click Start Server Instance.
In the Application Navigator, select the EssDemoApp application.
In the Application Navigator from the Application Menu select Deploy > EssDemoApp > to > IntegratedWLSConnection, as shown in Figure 5-28.
Oracle JDeveloper shows the Deployment Configuration page, as shown in Figure 5-29. Select the appropriate options for your Metadata Repository.
Click Deploy.
Verify the deployment using the Deployment Log.
To run the sample application you access the EssDemo servlet in a browser.
To access the EssDemo servlet:
Enter the following URL in a browser:
http://host:http-port/context-root/essdemo
For example,
http://myserver.us.oracle.com:7101/EssDemoApp/essdemo
This shows the EssDemo servlet, as shown in Figure 5-30.
Select a job definition from the Job drop-down menu.
Select a value from the Schedule drop-down menu.
Click Submit.
Refresh the browser to see the progress of the job in the Request Status area, as shown in Figure 5-31.
Using the sample application and the EssDemo servlet you can remove completed jobs from the Request Status list.
To remove completed jobs:
Click Purge to purge a request.
Click Cancel to cancel a request that is either RUNNING
or WAITING
.
This section covers common problems and solutions for these problems.
Problem: sqlplus: Command not found.
Solution: Run the Oracle Database commands in an environment that includes Oracle Database.
Problem: SP2-0310: unable to open file "createuser_ess_oracle.sql"
Solution: Change to the /rcu/integration/ess/sql
directory before running sqlplus scripts.
Problem:
404 Not Found Resource /EssDemoApp-ViewController-context-root/essdemo not found on this server
Solution: This and similar problems can be due to not using a URL that matches the root URL that you specify when set the context-root on the URL to access the application. To use a context-root that matches the deployed application, use the value that you specified.
To check and set the context-root value in the WAR archive:
Select the ViewController project.
Right-click and from the dropdown list select Project Properties.
In the navigator, select Deployment.
In the Deployment Profiles area, select essdemoapp and click Edit.
Choose the desired context-root, this forms the context-root on the URL to access the application.
In the General area, select Specify Java EE Web Context Root.
For the Java EE Web Context Root: text entry area, enter EssDemoApp
.
In the WAR Deployment Profile Properties window, click OK.
In the Project Properties window, click OK.
Problem: Unresolved application library references, defined in weblogic-application.xml: [Extension-Name: oracle.ess, exact-match: false]..
Deployment fails with errors. For example:
09:30:59 AM] Building... [09:31:00 AM] Deploying 2 profiles... [09:31:01 AM] Wrote Web Application Module to /scratch/sched7/mywork/EssDemoApp/ViewController/deploy/EssDemoApp_ViewController_webapp1.war [09:31:01 AM] removed bundleresolver.jar from APP-INF because it cannot be part of an EJB deployment[09:31:01 AM] Wrote Enterprise Application Module to /scratch/sched7/mywork/EssDemoApp/deploy/EssDemoApp_application1.ear [09:31:02 AM] Deploying Application... [09:31:04 AM] [Deployer:149193]Deployment of application 'EssDemoApp_application1' has failed on 'DefaultServer' [09:31:04 AM] [Deployer:149034]An exception occurred for task [Deployer:149026]deploy application EssDemoApp_application1 on DefaultServer.: [J2EE:160149]Error while processing library references. Unresolved application library references, defined in weblogic-application.xml: [Extension-Name: oracle.ess, exact-match: false].. [09:31:05 AM] Weblogic Server Exception: weblogic.management.DeploymentException: [J2EE:160149]Error while processing library references. Unresolved application library references, defined in weblogic-application.xml: [Extension-Name: oracle.ess, exact-match: false]. [09:31:05 AM] See server logs or server console for more details. [09:31:05 AM] weblogic.management.DeploymentException: [J2EE:160149]Error while processing library references. Unresolved application library references, defined in weblogic-application.xml: [Extension-Name: oracle.ess, exact-match: false]. [09:31:05 AM] #### Deployment incomplete. #### [09:31:05 AM] Deployment Failed
Solution: This deployment error can be seen when the application is correct, but the Oracle WebLogic Server configuration is not correct. The configuration includes the step, 3.1.4, "Create WLS domain". This configuration step is required.
You need to create the Oracle Enterprise Scheduling Service Oracle Database schema. Oracle Enterprise Scheduling Service uses this schema to maintain information about job requests.
Note:
In the Oracle Fusion Applications environment, this step is not required. In this environment the database is installed with the Oracle Enterprise Scheduling Service schema pre-configured. Thus, in this environment you can skip this step.In order to create the Oracle Enterprise Scheduling Service database schema, you need to install Oracle JDeveloper for use with Oracle Enterprise Scheduling Service. For more information, see the Oracle Fusion Applications Installation Guide.
If you have been running with previous version of the Oracle Enterprise Scheduling Service runtime schema, or if for any reason you need to drop the schema, you can do this using the dropschema_ess_oracle.sql
script.
Use these steps only to drop the Oracle Enterprise Scheduling Service runtime schema. These steps clean up certain database objects and then drop the schema user. Note that simply dropping the Oracle Enterprise Scheduling Service schema is not sufficient to correctly drop and remove an existing schema.
Note:
For a first time installation you do not need to perform these steps. Only use these steps if you need to drop the database schema due to a previous installation error or to clean up your database after a previous use of Oracle Enterprise Scheduling Service.To drop the database schema:
Terminate any container that is using Oracle Enterprise Scheduling Service schema.
Change to the ess/sql
directory with the following command:
% cd JDEV_install_dir/rcu/integration/ess/sql
Do the following, when connected as SYS or as SYSDBA. In the text, ess_schema represents Oracle Enterprise Scheduling Service schema being removed:
@dropschema_ess_oracle.sql ess_schema alter session set current_schema=sys; drop user ess_schema cascade;
Example in which ess_schema is oraess:
> @dropschema_ess_oracle.sql oraess > alter session set current_schema=sys; > drop user oraess cascade; > exit
When you build and deploy Oracle Enterprise Scheduling Service applications, you can use two split applications — a job submission application, a submitter, and a job execution application, a hosting application. Using this design you need to configure and deploy each application with options that support such a split configuration. In addition, some Oracle Enterprise Scheduling Service deployments use a separate Oracle WebLogic Server for the hosting and the submitting applications; for this deployment option the submitting application and the hosting application are deployed to separate Oracle WebLogic Servers. When the submitter application and the hosting application for Oracle Enterprise Scheduling Service run on separate Oracle WebLogic Servers, you need to configure the Oracle WebLogic Server for the hosting application so that the submitting application can find the hosting application.
Note:
This chapter includes a tutorial that uses an older release of Oracle JDeveloper. This content is deprecated. For development with a current version of Oracle JDeveloper, see Chapter 4, "Using Oracle JDeveloper to Generate an Oracle Enterprise Scheduling Service Application".To build the sample split applications, you do the following:
Build a back-end hosting application that includes the code to be scheduled and run.
Build a front-end submitter application initiates the job requests.
Using Oracle JDeveloper you create the back-end application. To create the back-end sample application you do the following:
Create a back-end application and project.
Configure security.
Define the deployment descriptors.
Create the Java class that implements the Oracle Enterprise Scheduling Service executable interface.
Create the Oracle Enterprise Scheduling Service metadata to describe the job
Assemble the application.
Deploy the application.
To work with Oracle Enterprise Scheduling Service with a split application you use Oracle JDeveloper to create the back-end application and project, and to add Oracle Enterprise Scheduling Service extensions to the project.
To create the back-end hosting application:
From JDeveloper choose File > New from the main menu.
In the New Gallery, expand General, select Applications and then Generic Application, and click OK.
In the Name your application page of the Create Generic Application wizard, set the Application Name field to EssDemoApp
.
In the Name your project page, set the Project Name to SuperEss
.
This project is where you will create and save the Oracle Enterprise Scheduling Service metadata.
Add the EJB technology to the project.
In the Project Java Settings page, change the default package to oracle.apss.ess.howto
.
In the Configure EJB Settings page, select Generate ejb-jar.xml in this project and click Finish.
In the Application Navigator, right-click the SuperEss project and select Project Properties.
In the Project Properties dialog, expand Project Source Paths and click the Resources navigation tab.
Select Include Content from Subfolders.
Click the Libraries and Classpath navigation tab.
Click Add Library, select Enterprise Scheduler Extensions, and click OK.
You need to create a user that is assigned to the EssDempAppRole role.
To configure security for the back-end hosting application:
Select Application > Secure > Configure ADF Security from the main menu.
In the ADF Security page of the Configure ADF Security wizard, select ADF Authentication.
In the Authentication Type page, accept the default values as this application will not have a web module to secure.
Click Finish.
A file named jps-config.xml
is generated. You can find this file in the Application Resources panel by expanding Descriptors, and expanding META-INF. This file contains a security context or security stripe named after the application.
Select Application > Secure > Users from the main menu.
A file named jps-config.xml
is generated.
In the overview editor for the jps-config.xml
file, click the Add icon in the Users list.
Set the name to EssDemoAppUser
and set the password to welcome1
.
Click the Application Roles navigation tab.
Click the Add icon in the Roles list and choose Add New Role.
Set the name to EssDemoAppRole
.
Click the Add icon in the Mappings tab and choose Add User.
Select EssDemoAppUser
and click OK.
The sample application needs to contain the required EJB descriptors. You need to create the ejb-jar.xml
and weblogic-ejb-jar.xml
files and include these files with any Java implementation class that you create.
Oracle Enterprise Scheduling Service requires an application to assemble and provide an EJB JAR so that Oracle Enterprise Scheduling Service can find its entry point in the application while running job requests on behalf of the application. This EJB jar should have its required EJB descriptors in ejb-jar.xml
and weblogic-ejb-jar
, as well as any Java class implementations that are going to be submitted to Oracle Enterprise Scheduling Service. The descriptor files ejb-jar.xml
and weblogic-ejb-jar
must contain descriptions for the Oracle Enterprise Scheduling Service EJBs.
The Oracle Enterprise Scheduling Service back-end application is deployed to Oracle WebLogic Server. You need to create a deployment profile in Oracle JDeveloper to deploy the EssDemoApp
application.
The EssDemoApp
application is a standalone application that contains an Oracle Enterprise Scheduling Service Java job and includes the required Oracle Enterprise Scheduling Service metadata, an Oracle Enterprise Scheduling Service message-driven bean (MDB), and the EJB descriptors for the application. This application does not perform Oracle Enterprise Scheduling Service submit API; in this hosting application the submission occurs in the front-end submitter application. In the hosting application, EssDemoApp, the weblogic-ejb-jar.xml
exposes the EJB remote interface through JNDI (using the EJB remote interface allows for the job submission to occur in the front-end application).
You also need to create the weblogic-application.xml
file to include the oracle.ess
library, to add an Oracle Enterprise Scheduling Service listener, and to indicate which stripe to use to upload the jazn-data.xml
policy.
To define the deployment descriptors for the back-end hosting application:
In the Application Navigator, expand SuperEss, expand Application Sources, expand META-INF, and double-click ejb-jar.xml.
Replace the contents of the file with the XML shown in Example 5-6
Example 5-6 Contents to Copy to ejb-jar.xml for a back-end Hosting Application
<?xml version = '1.0' encoding = 'UTF-8'?> <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" 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/ejb-jar_3_0.xsd" version="3.0"> <display-name>ESS</display-name> <enterprise-beans> <message-driven> <ejb-name>ESSAppEndpoint</ejb-name> <ejb-class>oracle.as.scheduler.ejb.EssAppEndpointBean</ejb-class> <activation-config> <activation-config-property> <!-- The "applicationName" property specifies the logical name used - by Oracle Enterprise Scheduling Service to identify this application. - This name is independent of the application name used when - deploying the application to the container. This decoupling - allows applications to safely hardcode the logical application - name in source code without having to worry about the more - frequently changed deployment name. - - Note: The name given here must also be specified in the - SYS_effectiveApplication property of each job definition and - job set of this application. --> <activation-config-property-name>applicationName</activation-config-property-name> <activation-config-property-value>EssDemoApp</activation-config-property-value> </activation-config-property> <activation-config-property> <!-- The "applicationStripe" property specifies which JPS security - stripe or "security context" Oracle Enterprise Scheduling Service should - use to perform security checks. - - The value here must be the same as the "injection-target-name" - value used by the "oracle.security.jps.ee.ejb.JpsInterceptor" - interceptor descriptor below. - - Note: When creating jps-config.xml through JDev, it will create - default security context using the JDev workspace name. In - order to simplify things, we will use the JDev workspace name - as our value. Otherwise, you will have to rename the security - context created by JDev or create your own. --> <activation-config-property-name>applicationStripe </activation-config-property-name> <activation-config-property-value>EssDemoApp </activation-config-property-value> </activation-config-property> </activation-config> </message-driven> <!-- The AsyncBean allows asynchronous Java jobs to notify - Oracle Enterprise Scheduling Service of its status through Java EE EJB APIs. - It is recommended to use the WebService callback pattern - instead of the EJB callbacks wherever possible. --> <session> <description>Async Request Bean</description> <ejb-name>AsyncRequestBean</ejb-name> <ejb-class>oracle.as.scheduler.ejb.AsyncRequestBean</ejb-class> </session> <!-- The Runtime Service allows users to interact with an Executable. - Operations include submitting, cancelling, querying, etc. --> <session> <description>Runtime Session Bean</description> <ejb-name>RuntimeServiceBean</ejb-name> <ejb-class>oracle.as.scheduler.ejb.RuntimeServiceBean</ejb-class> </session> <!-- The Metadata Service allows user to interact with - Oracle Enterprise Scheduling Service, metadata including job definitions, - job sets, job types, schedules, and so on. Operations include reading, - writing, querying, copying, deleting, and so on. --> <session> <description>Metadata Session Bean</description> <ejb-name>MetadataServiceBean</ejb-name> <ejb-class>oracle.as.scheduler.ejb.MetadataServiceBean</ejb-class> </session> </enterprise-beans> <!-- - The JPS interceptor is used by JPS (Java Platform Security) in order to - perform security checks. The "stripe name" is usually associated with - the application name but some groups split their security permissions - between Oracle ADF grants and Oracle Enterprise Scheduling Service grants, creating - two stripes. - For example, the Oracle ADF grants would live in the "MyApp" stripe while - the Oracle Enterprise Scheduling Service grants would live in the "MyAppEss". - - Note: For this example, we will use only 1 stripe. - - Note: When creating jps-config.xml through JDev, it will create - default security context using the JDev workspace name. In - order to simplify things, we will use the JDev workspace name - as our value. Otherwise, you will have to rename the security - context created by JDev or create your own. --> <interceptors> <interceptor> <interceptor-class>oracle.security.jps.ee.ejb.JpsInterceptor</interceptor-class> <env-entry> <env-entry-name>application.name</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>EssDemoApp</env-entry-value> <injection-target> <injection-target-class>oracle.security.jps.ee.ejb.JpsInterceptor</injection-target-class> <injection-target-name>application_name</injection-target-name> </injection-target> </env-entry> </interceptor> </interceptors> </ejb-jar>
In Application Navigator, right-click the SuperEss project and select New.
In the New Gallery, expand General, select Deployment Descriptors and then Weblogic Deployment Descriptor, and click OK.
In the Select Descriptor page select weblogic-ejb-jar.xml.
Click Next, click Next again, and click Finish.
In the source editor, replace the contents of the weblogic-ejb-jar.xml
file that you just created with the XML shown in Example 5-7.
This XML associates the MDB in the ejb-jar.xml
file with the Oracle Enterprise Scheduling Service Resource Adapter. Without this XML, the application would not know what to talk to.
Example 5-7 Contents to Copy to weblogic-ejb-jar.xml for a Back-End Hosting Application
<?xml version = '1.0' encoding = 'UTF-8'?> <weblogic-ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-ejb-jar http://www.bea.com/ns/weblogic/weblogic-ejb-jar/1.0/weblogic-ejb-jar.xsd" xmlns="http://www.bea.com/ns/weblogic/weblogic-ejb-jar"> <weblogic-enterprise-bean> <ejb-name>ESSAppEndpoint</ejb-name> <message-driven-descriptor> <resource-adapter-jndi-name>ess/ra</resource-adapter-jndi-name> </message-driven-descriptor> <dispatch-policy>ESSRAWM</dispatch-policy> </weblogic-enterprise-bean> </weblogic-ejb-jar>
In Application Navigator, right-click the SuperEss project and select New.
In the New Gallery, expand General, select Deployment Descriptors and then Weblogic Deployment Descriptor, and click OK.
In the Select Descriptor page select weblogic-application.xml.
Click Next, click Next again, and click Finish.
In the source editor, replace the contents of the weblogic-application.xml
file that you just created with the XML shown in Example 5-8.
Example 5-8 Contents to Copy to weblogic-application.xml for a Back-End Hosting Application
<?xml version = '1.0' encoding = 'UTF-8'?> <weblogic-application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-application http://www.bea.com/ns/weblogic/weblogic-application/1.0/weblogic-application.xsd" xmlns="http://www.bea.com/ns/weblogic/weblogic-application"> <!-- The following application parameter tells JPS which stripe it should - use to upload the jazn-data.xml policy. If this parameter is not - specified, it will use the Java EE deployment name plus the version - number (e.g. EssDemoApp#V2.0). --> <application-param> <param-name>jps.policystore.applicationid</param-name> <param-value>EssDemoApp</param-value> </application-param> <!-- This listener allows JPS to configure itself and upload the - jazn-data.xml policy to the appropriate stripe --> <listener> <listener-class>oracle.security.jps.wls.listeners.JpsApplicationLifecycleListener</listener-class> </listener> <!-- This listener allows MDS to configure itself and upload any metadata - as defined by the MAR profile and adf-config.xml --> <listener> <listener-class>oracle.mds.lcm.weblogic.WLLifecycleListener</listener-class> </listener> <!-- This listener allows Oracle Enterprise Scheduling Service to configure itself --> <listener> <listener-class>oracle.as.scheduler.platform.wls.deploy.ESSApplicationLifecycleListener</listener-class> </listener> <!-- This shared library contains all the Oracle Enterprise Scheduling Service classes --> <library-ref> <library-name>oracle.ess</library-name> </library-ref> </weblogic-application>
To define an application that runs a Java class under control of Oracle Enterprise Scheduling Service you need to create the Java class that implements the Oracle Enterprise Scheduling Service Executable
interface. The Executable
interface specifies the contract that allows you to use Oracle Enterprise Scheduling Service to invoke a Java class.
A Java class that implements the Executable
interface must provide an empty execute()
method.
To create a Java class that implements the executable Interface:
In the Application Navigator, right-click the SuperEss project and choose New.
In the New Gallery, expand General, select Java and then Java Class, and click OK.
In the Create Java Class dialog, set the name to HelloWorldJob
.
Set the package to oracle.apps.ess.howto
.
Click the Add icon, add the oracle.as.scheduler.Executable
interface, and click OK.
In other fields accept the defaults.
Click OK.
In the source editor, replace the generated contents of the HelloWorldJob.java
file with the code shown in Example 5-9.
Example 5-9 Oracle Enterprise Scheduling Service HelloWorldJob Java Class
package oracle.apps.ess.howto;import java.util.logging.Logger;import oracle.as.scheduler.Executable;import oracle.as.scheduler.ExecutionCancelledException;import oracle.as.scheduler.ExecutionErrorException;import oracle.as.scheduler.ExecutionPausedException;import oracle.as.scheduler.ExecutionWarningException;import oracle.as.scheduler.RequestExecutionContext;import oracle.as.scheduler.RequestParameters;public class HelloWorldJob implements Executable { public HelloWorldJob() { super(); } public void execute(RequestExecutionContext requestExecutionContext, RequestParameters requestParameters) throws ExecutionErrorException, ExecutionWarningException, ExecutionCancelledException, ExecutionPausedException { printBanner(requestExecutionContext, requestParameters); } protected void printBanner(RequestExecutionContext requestExecutionContext, RequestParameters requestParameters) { StringBuilder sb = new StringBuilder(1000); sb.append("\n=================================="); sb.append("\n= EssDemoApp request is now running"); long myRequestId = requestExecutionContext.getRequestId(); sb.append("\n= Request Id = " + myRequestId); sb.append("\n= Request Properties:"); for (String paramKey : requestParameters.getNames()) { Object paramValue = requestParameters.getValue(paramKey); sb.append("\n=\t(" + paramKey + ", " + paramValue + ")"); } sb.append("\n="); sb.append("\n=================================="); Logger logger = Logger.getLogger("oracle.apps.ess.howto"); logger.info(sb.toString()); }}
To use the Oracle Enterprise Scheduling Service split application to submit a job request you need to create metadata that defines a job request, including the following:
A job type: this specifies an execution type and defines a common set of parameters for a job request.
A job definition: this is the basic unit of work that defines a job request in Oracle Enterprise Scheduling Service.
Note:
For Oracle Fusion Applications use cases, use the prepackaged Oracle Enterprise Scheduling Service job types instead of creating your own. For demonstration purposes, you will create your own job type.To create metadata for the back-end hosting application:
In the Application Navigator, right-click the SuperEss project and choose New.
In the New Gallery, select the All Technologies tab.
Expand Business Tier, select Enterprise Scheduler Metadata and then Job Type, and click OK.
In the Create Job Type dialog, specify the following:
In the Name field, enter HelloWorldJobType
.
In the Package field, enter /oracle/apps/ess/howto/
.
Select JAVA_TYPE from the Execution Type dropdown list.
Click OK. This creates the HelloWorldJobType.xml
file and Oracle JDeveloper displays the file in the editor.
In the editor window, set the description to HelloWorld Example
.
Set the class name to oracle.apps.ess.howto.HelloWorldJob
.
In the Application Navigator, right-click the SuperEss project and choose New.
Expand Business Tier, select Enterprise Scheduler Metadata and then Job Definition, and click OK.
In the Create Job Definition dialog, specify the following:
Set the name to HelloWorldJobDef
.
Set the package to /oracle/apps/ess/howto/
.
Set the job type to /oracle/apps/ess/howto/HelloWorldJobType
.
Click OK. This creates the HelloWorldJobDef.xml
file and Oracle JDeveloper displays the file in the editor.
In the editor window, set the description to HelloWorld Example
.
Click the Add icon in the System Properties section.
In the Add System Property dialog, select SYS_effectiveApplication from the Name dropdown list.
Set the initial value to EssDemoApp
and click OK.
Click the Add icon in the Access Control section.
In the Add Access Control dialog, ensure that EssDemoApp role is selected in the Role dropdown list.
This is the role that you created in Section 5.9.1.2, "Configuring Security for the Back-End Hosting Application."
Select Read and select Execute.
Click OK.
After you create the back-end sample application you use Oracle JDeveloper to assemble the application.
To assemble the back-end application you do the following:
Create the EJB Java Archive
Create the application MAR and EAR files
The EJB Java archive file includes descriptors for the Java job implementations.
To assemble the EJB JAR file for the back-end hosting application:
In Application Navigator, right-click the SuperEss project and select Rebuild SuperEss.jpr.
In the Messages Log you should see a successful compilation message, for example:
[3:40:22 PM] Successful compilation: 0 errors, 0 warnings.
In Application Navigator, right-click the SuperEss project and choose New.
In the New Gallery, expand General, select Deployment Profiles and then EJB JAR File, and click OK.
In the Create Deployment Profile dialog, set the Deployment Profile Name to JAR_SuperEssEjbJar
.
Optionally, in the Edit EJB JAR Deployment Profile Properties dialog, expand File Groups, expand Project Output, and select Filters and clear the essmeta check box.
Clearing this check box prevents the JAR file from being cluttered with unnecessary XML files and reduces the overall memory footprint.
On the EJB JAR Deployment Profile Properties dialog, click OK.
On the Project Properties dialog, click OK.
The sample application needs to contain the MAR profile and the EAR file that assembles the back-end application.
To create the MAR and EAR files for the back-end hosting application:
From the main menu, choose Application Menu > Application Properties...
In the Application Properties dialog, click the Deployment navigation tab and click New.
In the Create Deployment Profile dialog, select MAR File from the Archive Type dropdown list.
In the Name field, enter MAR_EssDemoAppMar
and click OK.
In the Edit MAR Deployment Profile dialog, expand Metadata File Groups and click User Metadata.
Click Add.
In the Add Contributor dialog add the essmeta
directory.
For example, if your work space is at /tmp/EssDemoApp
, then the directory to add is /tmp/EssDemoApp/SuperEss/essmeta
.
On the Add Contributor dialog, click OK.
In the navigator expand Metadata File Groups and User Metadata and select Directories.
Expand the directories and select the deepest directory of the package name, which is the howto
directory.
The directory that you select forms the MDS namespace. In order to avoid conflicts, you must select the most specific namespace.
Click OK.
In the Deployment page of the Application Properties dialog, click New.
In the Create Deployment Profile dialog, select EAR File from the Archive Type dropdown list.
In the Name field, enter EAR_EssDemoAppEar
and click OK.
In the Edit EAR Deployment Profile dialog, click the General navigation tab and enter EssDemoApp
in the Application Name field.
Click the Application Assembly navigation tab, then select MAR_ESSDemoAppMar
and select JAR_SuperEssEjbJar
.
Click OK.
In the Application Properties dialog, click OK.
After assembling the application, you can deploy it to the server.
To deploy the back-end hosting application:
From the main menu, choose Application > Deploy > EAR_EssDemoAppEar...
Set up and deploy the application to a container.
When the Deployment Configuration dialog appears, make a note of the default values, but do not change them.
In an Oracle Enterprise Scheduling Service split application you use the Oracle Enterprise Scheduling Service APIs to submit job requests from a front-end application. The EssDemoAppUI
application provides a Java servlet for a servlet based user interface for submitting job requests (using Oracle Enterprise Scheduling Service).
To create the front-end submitter sample application you do the following:
Create a front-end application and project.
Configure the ejb-jar.xml
file.
Create the web project
Configure security.
Create the HTTP servlet.
Edit the web.xml
file.
Edit the weblogic-application.xml
file.
Edit the adf-config
file.
Assemble the application.
Deploy the application.
You use JDeveloper to build the front-end submitter application using similar steps as you used for the back-end hosting application.
To create the front-end submitter application:
Complete the steps in Section 5.9.1.1, "Creating the Back-End Hosting Application" but this time use ESSDemoAppUI
as the name of the application.
In the Application Navigator, right-click the SuperEss project and choose New.
In the New Gallery, select General, select Folder, and click OK.
Set the folder name to essmeta
and click OK.
You need to add entries to the ejb-jar.xml file to enable asynchronous Java jobs to notify the Oracle Enterprise Scheduling Service of its status and to enable users to interact with executable operations, such as submitting operations, and with Oracle Enterprise Scheduling Service metadata, such as job definitions. You also need to indicate which stripe to use.
To define the deployment descriptors for the front-end submitter application:
In the Application Navigator, expand SuperEss, expand Application Sources, expand META-INF, and double-click ejb-jar.xml.
Replace the contents of the file with the XML shown in Example 5-10
Example 5-10 Contents to Copy to ejb-jar.xml for a Front-End Submitter Application
<?xml version = '1.0' encoding = 'UTF-8'?> <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" 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/ejb-jar_3_0.xsd" version="3.0"> <display-name>ESS</display-name> <enterprise-beans> <!-- Note that the UI application does NOT have a message driven bean. - This is because the UI application does not run any jobs. The UI - application does have the other EJBs. --> <!-- The AsyncBean allows asynchronous Java jobs to notify - Oracle Enterprise Scheduling Service of its status through Java EE EJB APIs. - It is recommended to instead use the WebService callback pattern - instead of the EJB callbacks wherever possible. --> <session> <description>Async Request Bean</description> <ejb-name>AsyncRequestBean</ejb-name> <ejb-class>oracle.as.scheduler.ejb.AsyncRequestBean</ejb-class> </session> <!-- The Runtime Service allows users to interact with an Executable. - Operations include submitting, cancelling, querying, etc. --> <session> <description>Runtime Session Bean</description> <ejb-name>RuntimeServiceBean</ejb-name> <ejb-class>oracle.as.scheduler.ejb.RuntimeServiceBean</ejb-class> </session> <!-- The Metadata Service allows users to interact with - Oracle Enterprise Scheduling Service, metadata, including job definitions, - job sets, job types, schedules, and so on. - Operations include reading, writing, querying, copying, deleting, - and so on. --> <session> <description>Metadata Session Bean</description> <ejb-name>MetadataServiceBean</ejb-name> <ejb-class>oracle.as.scheduler.ejb.MetadataServiceBean</ejb-class> </session> </enterprise-beans> <!-- - The JPS interceptor is used by JPS (Java Platform Security) in order to - perform security checks. The "stripe name" is usually associated with - the application name but some groups split their security permissions - between Oracle ADF grants and Oracle Enterprise Scheduling Service grants, thereby - creating two stripes. For example, the Oracle ADF grants would live - in the "MyApp" stripe while the Oracle Enterprise Scheduling Service - grants would live in the "MyAppEss". - - Note: For this example, we will use only 1 stripe. - - Note: When creating jps-config.xml through JDev, it will create - default security context using the JDev workspace name. In - order to simplify things, we will use the JDev workspace name - as our value. Otherwise, you will have to rename the security - context created by JDev or create your own. --> <interceptors> <interceptor> <interceptor-class>oracle.security.jps.ee.ejb.JpsInterceptor</interceptor-class> <env-entry> <env-entry-name>application.name</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>EssDemoApp</env-entry-value> <injection-target> <injection-target-class>oracle.security.jps.ee.ejb.JpsInterceptor</injection-target-class> <injection-target-name>application_name</injection-target-name> </injection-target> </env-entry> </interceptor> </interceptors> </ejb-jar>
You need to create a web project for the servlet.
To create the SuperWeb project:
Right-click the SuperEss project and choose New.
In the New Gallery, expand General, select Projects and then Generic Project, and click OK.
In the Name your application page of the Create Generic Application wizard, set the Application Name field to SuperWeb
.
In the Name your project page, set the Project Name to SuperEss
.
Add the JSP and Servlets technology to the project.
In the Project Java Settings page, change the default package to oracle.apss.ess.howto
and click Finish.
In the Application Navigator, right-click the SuperWeb project and choose Project Properties.
Click the Libraries and Classpath navigation tab.
Click Add Library, select ADF Web Runtime and Enterprise Scheduler Extensions, and click OK.
You need to configure security for the application. You do not have to create any users or roles as the EssDemoAppUI application will simply share the users and roles created by the EssDemoApp application.
To configure security for the front-end submitter application:
Select Application > Secure > Configure ADF Security from the main menu.
In the ADF Security page of the Configure ADF Security wizard, select ADF Authentication.
In the Authentication Type page, select SuperWeb.jpr from the Web Project dropdown list.
Select HTTP Basic Authentication.
Click Finish.
A file named jps-config.xml
is generated. You can find this file in the Application Resources panel by expanding Descriptors, and expanding META-INF.
Normally, more complex user interfaces that are built on heavy weight frameworks such as Oracle Application Development Framework are employed, but for the sake of simplicity, you use a basic HTTP servlet for the submitter application.
To create the HTTP Servlet for the front-end submitter application:
Right-click the SuperEss project and choose New.
In the New Gallery, expand Web Tier, select Servlets and then HTTP Servlet, and click OK.
In the Web Application page of the Web Application wizard, select Servlet 2.5\JSP 2.1 (Java EE 1.5).
In the Create HTTP Servlet - Step 1 of 3: Servlet Information page, enter EssDemoAppServlet
in the Class field.
Enter oracle.apps.ess.howto
in the Package field and click Next.
Click Finish.
In the source editor, replace the contents of ESSDemoAppServlet.java with the code in Example 5-11.
Example 5-11 HTTP Servlet Code for the Front-End Submitter Application
package oracle.apps.ess.howto; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Calendar; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import oracle.as.scheduler.MetadataObjectId; import oracle.as.scheduler.MetadataObjectId.MetadataObjectType; import oracle.as.scheduler.MetadataService; import oracle.as.scheduler.MetadataService.QueryField; import oracle.as.scheduler.MetadataServiceHandle; import oracle.as.scheduler.RequestDetail; import oracle.as.scheduler.RequestParameters; import oracle.as.scheduler.RuntimeService; import oracle.as.scheduler.RuntimeServiceHandle; import oracle.as.scheduler.State; import oracle.as.scheduler.core.JndiUtil; public class EssDemoAppServlet extends HttpServlet { @SuppressWarnings("compatibility:4685800289380934682") private static final long serialVersionUID = 1L; private static final String CONTENT_TYPE = "text/html; charset=UTF-8"; private static final String MESSAGE_KEY = "Message"; private static final String PATH_SUBMIT = "/submitRequest"; private static final String PATH_ALTER = "/alterRequest"; private static final String MDO_SEP = ";"; private static final String ACTION_CANCEL = "Cancel"; private static final String ESS_UNAVAIL_MSG = "<p>Enterprise Scheduler Service is currently unavailable. Cause: %s</p>"; private enum PseudoScheduleChoices { Immediately(0), InTenSeconds(10), InTenMinutes(10 * 60); @SuppressWarnings("compatibility:-5637079380819677366") private static final long serialVersionUID = 1L; private int m_seconds; private PseudoScheduleChoices(int seconds) { m_seconds = seconds; } public int getSeconds() { return m_seconds; } } public EssDemoAppServlet() throws ServletException { super(); } @Override public void init(ServletConfig config) throws ServletException { super.init(config); } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(CONTENT_TYPE); HttpSession session = request.getSession(true); String lastMessage = String.valueOf(session.getAttribute(MESSAGE_KEY)); if ("null".equals(lastMessage)) { lastMessage = ""; } try { RuntimeLists runtimeLists = getRuntimeLists(); MetadataLists metadataLists = getMetadataLists(); renderResponse(metadataLists, runtimeLists, request, response, lastMessage); } catch (ServletException se) { throw se; } catch (Exception e) { throw new ServletException(e); } } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(CONTENT_TYPE); request.setCharacterEncoding("UTF-8"); HttpSession session = request.getSession(true); String pathInfo = request.getPathInfo(); // Clear the message on every post request StringBuilder message = new StringBuilder(""); try { // Select each handler based on the form action if ("".equals(pathInfo)) { // No processing } else if (PATH_SUBMIT.equals(pathInfo)) { postSubmitRequest(request, message); } else if (PATH_ALTER.equals(pathInfo)) { postAlterRequest(request, message); } else { message.append(String.format("<p>No handler for pathInfo=%s</p>", pathInfo)); } } catch (ServletException se) { Throwable t = se.getCause(); String cause = (t == null) ? se.toString() : t.toString(); message.append (String.format(ESS_UNAVAIL_MSG, cause)); } // Storing the messages in the session allows them to persist // through the redirect and across refreshes. session.setAttribute(MESSAGE_KEY, message.toString()); // render the page by redirecting to doGet(); this intentionally // strips the actions and post data from the request. response.sendRedirect(request.getContextPath() + request.getServletPath()); } /** * Handle the job submission form. * @param request * @param message * @throws ServletException */ private void postSubmitRequest(HttpServletRequest request, StringBuilder message) throws ServletException { String jobDefName = request.getParameter("job"); String scheduleDefName = request.getParameter("schedule"); // Various required args for submission Calendar start = Calendar.getInstance(); start.add(Calendar.SECOND, 2); // Launch the job based on form contents if (jobDefName == null || scheduleDefName == null) { message.append("Both a job name and a schedule name must be specified\n"); } else { PseudoScheduleChoices pseudoSchedule = null; // See if schedule given is actually a pseudo schedule try { pseudoSchedule = PseudoScheduleChoices.valueOf(scheduleDefName); } catch (IllegalArgumentException e) { // The string is not a valid member of the enum pseudoSchedule = null; } MetadataObjectId scheduleDefId = null; String scheduleDefNamePart = null; MetadataObjectId jobDefId = stringToMetadataObjectId(jobDefName); // Don't look up schedules that aren't real if (pseudoSchedule != null) { scheduleDefNamePart = scheduleDefName; start.add(Calendar.SECOND, pseudoSchedule.getSeconds()); } else { scheduleDefId = stringToMetadataObjectId(scheduleDefName); scheduleDefNamePart = scheduleDefId.getNamePart(); } String jobDefNamePart = jobDefId.getNamePart(); String requestDesc = jobDefNamePart + "@" + scheduleDefNamePart; Logger logger = getLogger(); long requestId = submitRequest(pseudoSchedule, requestDesc, jobDefId, scheduleDefId, start, logger); // Populate the message block based on results message.append(String.format("<p>New request %d launched using %s</p>", requestId, requestDesc)); } } private Long submitRequest(final PseudoScheduleChoices pseudoSchedule, final String requestDesc, final MetadataObjectId jobDefId, final MetadataObjectId scheduleDefId, final Calendar start, final Logger logger) throws ServletException { RuntimeServicePayload<Long> myPayload = new RuntimeServicePayload<Long>() { @Override Long execute(RuntimeService service, RuntimeServiceHandle handle, Logger logger) throws Exception { RequestParameters params = new RequestParameters(); return (null != pseudoSchedule) ? service.submitRequest(handle, requestDesc, jobDefId, start, params) : service.submitRequest(handle, requestDesc, jobDefId, scheduleDefId, null, start, null, params); } }; try { return performOperation(myPayload, logger); } catch (Exception e) { throw new ServletException("Error submitting request using job: " + jobDefId + " and schedule: " + scheduleDefId, e); } } /** * Handle the "Cancel" and "Purge" actions from the form enclosing * the Request Status table. * @param request * @param message * @throws ServletException */ private void postAlterRequest(HttpServletRequest request, StringBuilder message) throws ServletException { String cancelID = null; /* * there are a few assumptions going on here... * the HTTP button being used to transmit the action and * request is backwards from its normal usage (eg. the name * should be invariable, and the value variable). Because we * want to display either "Purge" or "Cancel" on the button, and * transmit the reqId with it, we are reversing the map entry * to get the key (which in this case will be the reqID), and * match it to the value (Purge or Cancel). * Assumptions are that there will be only one entry in the map * per request (one purge or cancel). Also, that the datatypes * for the key and value willl be those documented for * ServletRequest (<K,V> = <String, String[]>). */ Map requestMap = request.getParameterMap(); Iterator mapIter = requestMap.entrySet().iterator(); while (mapIter.hasNext()) { Map.Entry entry = (Map.Entry)mapIter.next(); String key = (String)entry.getKey(); String[] values = (String[])entry.getValue(); if (ACTION_CANCEL.equals(values[0])) { cancelID = key; } } if (cancelID != null) { try { final String cancelId2 = cancelID; RuntimeServicePayload<Void> myPayload = new RuntimeServicePayload<Void>() { @Override Void execute(RuntimeService service, RuntimeServiceHandle handle, Logger logger) throws Exception { service.cancelRequest(handle, Long.valueOf(cancelId2)); return null; } }; Logger logger = getLogger(); performOperation(myPayload, logger); message.append (String.format("<p>Cancelled request %s</p>", cancelID)); } catch (Exception e) { throw new ServletException ("Error canceling or purging request", e); } } else { message.append("<p>No purge or cancel action specified</p>"); } } private String metadataObjectIdToString(MetadataObjectId mdoID) throws ServletException { String mdoString = mdoID.getType().value() + MDO_SEP + mdoID.getPackagePart() + MDO_SEP + mdoID.getNamePart(); return mdoString; } private MetadataObjectId stringToMetadataObjectId(String mdoString) throws ServletException { String[] mdoStringParts = mdoString.split(Pattern.quote(MDO_SEP)); if (mdoStringParts.length != 3) { throw new ServletException(String.format("Unexpected number of components %d found " + "when converting %s to MetadataObjectID", mdoStringParts.length, mdoString)); } MetadataObjectType mdType = MetadataObjectType.getMOType(mdoStringParts[0]); String mdPackage = mdoStringParts[1]; String mdName = mdoStringParts[2]; MetadataObjectId mdoID = MetadataObjectId.createMetadataObjectId(mdType, mdPackage, mdName); return mdoID; } /** * this changes the format used in this class for job definitions to the one * which will be used in the runtime query. * @param strMetadataObject * @return string representing object in runtime store * @throws ServletException */ private String fixMetadataString(String strMetadataObject) throws ServletException { String fslash = "/"; String[] mdoStringParts = strMetadataObject.split(Pattern.quote(MDO_SEP)); if (mdoStringParts.length != 3) { throw new ServletException(String.format("Unexpected number of components %d found " + "when converting %s to MetadataObjectID", mdoStringParts.length, strMetadataObject)); } String[] trimStringParts = new String[mdoStringParts.length]; for (int i = 0; i < mdoStringParts.length; i++) { String mdoStringPart = mdoStringParts[i]; trimStringParts[i] = mdoStringPart.replaceAll(fslash, " ").trim(); } MetadataObjectType mdType = MetadataObjectType.getMOType(trimStringParts[0]); String mdPackage = fslash + trimStringParts[1]; String mdName = trimStringParts[2]; MetadataObjectId metadataObjId = MetadataObjectId.createMetadataObjectId(mdType, mdPackage, mdName); return metadataObjId.toString(); } private Set<String> getSetFromMetadataEnum(Enumeration<MetadataObjectId> enumMetadata) throws ServletException { Set<String> stringSet = new HashSet<String>(); while (enumMetadata.hasMoreElements()) { MetadataObjectId objId = enumMetadata.nextElement(); String strNamePart = objId.getNamePart(); stringSet.add(strNamePart); } return stringSet; } //**************************************************************************** // // HTML Rendering Methods // //**************************************************************************** /** * Rendering code for the page displayed. * In a real application this would be done using JSP, but this approach * keeps everything in one file to make the example easier to follow. * @param response The response object from the main request. * @param message Text that will appear in the message panel, may contain HTML * @throws IOException */ private void renderResponse(MetadataLists ml, RuntimeLists rl, HttpServletRequest request, HttpServletResponse response, String message) throws IOException, ServletException { response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); String urlBase = request.getContextPath() + request.getServletPath(); // Indents maintained for clarity out.println("<html>"); out.println("<head><title>EssDemo</title></head>"); out.println("<body>"); out.println("<table align=\"center\"><tbody>"); out.println(" <tr><td align=\"center\"><h1>Oracle Enterprise Scheduling Service Tutorial</h1></td></tr>"); out.println(" <tr><td align=\"center\"><table cellspacing=6><tr>"); // Job launch form out.println(" <td align=\"center\">"); out.println(" <h2>Launch Job</h2>"); renderLaunchJobForm(ml, out, urlBase); out.println(" </td>"); out.println(" <td align=\"center\" bgcolor=\"blue\" width=\"2\"/>"); out.println(" </tr></table></td></tr>"); out.println(" <tr><td bgcolor=\"red\"/></tr>"); // Message panel out.println(" <tr><td align=\"center\"><h3>Messages</h3></td></tr>"); out.println(" <tr><td>"); out.println(message); out.println(" </td></tr>"); out.println(" <tr><td bgcolor=\"red\"/></tr>"); // Request status out.println(" <tr><td align=\"center\">"); out.println(" <form name=\"attrs\" action=\"" + urlBase + PATH_ALTER + "\" method=\"post\">"); out.println(" <h2>Request Status</h2>"); out.println(" <table border=2><tbody>"); out.println(" <th>reqID</th>"); out.println(" <th>Description</th>"); out.println(" <th>Scheduled time</th>"); out.println(" <th>State</th>"); out.println(" <th>Action</th>"); renderStatusTable(out, rl.requestDetails); out.println(" </tbody></table>"); out.println(" </form>"); out.println(" </td></tr>"); out.println("</tbody></table>"); out.println("</body></html>"); out.close(); } private void renderLaunchJobForm(MetadataLists ml, PrintWriter out, String urlBase) throws ServletException { out.println(" <form name=\"attrs\" action=\"" + urlBase + PATH_SUBMIT + "\" method=\"post\">"); out.println(" <table><tbody>"); out.println(" <tr><td align=\"right\">"); out.println(" <b>Job:</b>"); out.println(" <select name=\"job\">"); renderMetadataChoices(out, ml.jobDefList, false); renderMetadataChoices(out, ml.jobSetList, false); out.println(" </select>"); out.println(" </td></tr>"); out.println(" <tr><td align=\"right\">"); out.println(" <b>Schedule:</b>"); out.println(" <select name=\"schedule\">"); renderPseudoScheduleChoices(out); renderMetadataChoices(out, ml.scheduleList, false); out.println(" </select>"); out.println(" </td></tr>"); out.println(" <tr><td align=\"center\">"); out.println(" <input name=\"submit\" value=\"Submit\" type=\"submit\">"); out.println(" </td></tr>"); out.println(" </tbody></table>"); out.println(" </form>"); } /** * * @param out - printwriter * @param jobChoices -- metadata to be displayed * @param bBlankFirst -- blank first (so that this param is not required) * @throws ServletException */ private void renderMetadataChoices(PrintWriter out, Enumeration<MetadataObjectId> jobChoices, boolean bBlankFirst) throws ServletException { if (jobChoices == null) return; boolean bFirst = true; while (jobChoices.hasMoreElements()) { MetadataObjectId job = jobChoices.nextElement(); String strJob = metadataObjectIdToString(job); String strNamePart = job.getNamePart(); if (strNamePart.compareTo("BatchPurgeJob") == 0) { continue; } else { if (bFirst && bBlankFirst) { out.printf("<option value=\"%s\">%s</option>", "", ""); bFirst = false; } out.printf("<option value=\"%s\">%s</option>", strJob, strNamePart); } } } /** * helper method for rendering choices based on strings, adding an empty * string to the beginning of the list * @param out * @param choices */ private void renderStringChoices(PrintWriter out, Set<String> choices) { if (choices == null) return; choices.add(""); SortedSet<String> sorted = new TreeSet<String>(choices); Iterator choiceIter = sorted.iterator(); while (choiceIter.hasNext()) { String choice = (String)choiceIter.next(); out.printf("<option value=\"%s\">%s</option>", choice, choice); } } private void renderPseudoScheduleChoices(PrintWriter out) { for (PseudoScheduleChoices c : PseudoScheduleChoices.values()) { out.printf("<option value=\"%s\">%s</option>", c, c); } } private void renderStatusTable (PrintWriter out, List<RequestDetail> reqDetails) { if (reqDetails == null) { return; } for (RequestDetail reqDetail : reqDetails) { State state = reqDetail.getState(); Calendar scheduledTime = reqDetail.getScheduledTime(); String scheduledTimeString = null; if (scheduledTime == null) { scheduledTimeString = "null scheduled time"; } else { scheduledTimeString = String.valueOf(scheduledTime.getTime()); } final String actionButton; if (!state.isTerminal()) { String action = ACTION_CANCEL; String reqId = String.valueOf(reqDetail.getRequestId()); actionButton = String.format ("<button type=submit value=%s name=\"%s\">%s</button>", action, reqId, action); } else { actionButton = " "; } out.printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", reqDetail.getRequestId(), reqDetail.getDescription(), scheduledTimeString, state, actionButton); } } private MetadataService getMetadataService() throws Exception { return JndiUtil.getMetadataServiceEJB(); } private RuntimeService getRuntimeService() throws Exception { return JndiUtil.getRuntimeServiceEJB(); } private abstract class Payload<SERVICE, HANDLE, RETURN> { abstract SERVICE getService() throws Exception; abstract HANDLE getHandle(SERVICE service) throws Exception; abstract void closeHandle(SERVICE service, HANDLE handle, boolean abort) throws Exception; abstract RETURN execute(SERVICE service, HANDLE handle, Logger logger) throws Exception; } private abstract class MetadataServicePayload<T> extends Payload<MetadataService, MetadataServiceHandle, T> { @Override MetadataService getService() throws Exception { return getMetadataService(); } @Override MetadataServiceHandle getHandle(MetadataService service) throws Exception { return service.open(); } @Override void closeHandle(MetadataService service, MetadataServiceHandle handle, boolean abort) throws Exception { service.close(handle, abort); } } private abstract class RuntimeServicePayload<T> extends Payload<RuntimeService, RuntimeServiceHandle, T> { @Override RuntimeService getService() throws Exception { return getRuntimeService(); } @Override RuntimeServiceHandle getHandle(RuntimeService service) throws Exception { return service.open(); } @Override void closeHandle(RuntimeService service, RuntimeServiceHandle handle, boolean abort) throws Exception { service.close(handle, abort); } } private <S, H, R> R performOperation (Payload<S, H, R> payload, Logger logger) throws Exception { S service = payload.getService(); H handle = payload.getHandle(service); Exception origException = null; try { return payload.execute(service, handle, logger); } catch (Exception e2) { origException = e2; throw e2; } finally { if (null != handle) { try { boolean abort = (null != origException); payload.closeHandle(service, handle, abort); } catch (Exception e2) { if (null != origException) { logger.log(Level.WARNING, "An error occurred while " + "closing handle, however, a previous failure was " + "detected. The following error will be logged " + "but not reported: " + stackTraceToString(e2)); } } } } } private final String stackTraceToString(Exception e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); pw.flush(); pw.close(); return sw.toString(); } private Logger getLogger() { return Logger.getLogger(this.getClass().getName()); } private class MetadataLists { private final Enumeration<MetadataObjectId> jobDefList; private final Enumeration<MetadataObjectId> jobSetList; private final Enumeration<MetadataObjectId> scheduleList; private final Enumeration<MetadataObjectId> jobTypeList; private MetadataLists(Enumeration<MetadataObjectId> jobDefList, Enumeration<MetadataObjectId> jobSetList, Enumeration<MetadataObjectId> scheduleList, Enumeration<MetadataObjectId> jobTypeList) { this.jobDefList = jobDefList; this.jobSetList = jobSetList; this.scheduleList = scheduleList; this.jobTypeList = jobTypeList; } } private class RuntimeLists { private final List<RequestDetail> requestDetails; private final Set<String> applicationChoices; private final Set<String> stateChoices; private final Set<MetadataObjectId> jobDefMDOChoices; private RuntimeLists(List<RequestDetail> requestDetails, Set<String> applicationChoices, Set<String> stateChoices, Set<MetadataObjectId> jobDefMDOChoices) { super(); this.requestDetails = requestDetails; this.applicationChoices = applicationChoices; this.stateChoices = stateChoices; this.jobDefMDOChoices = jobDefMDOChoices; } } /** * Retrieve lists of jobs, schedules, and status for use by the renderer * @throws ServletException */ private MetadataLists getMetadataLists() throws Exception { Logger logger = getLogger(); MetadataServicePayload<MetadataLists> myPayload = new MetadataServicePayload<MetadataLists>() { @Override MetadataLists execute(MetadataService service, MetadataServiceHandle handle, Logger logger) throws Exception { Enumeration<MetadataObjectId> jobDefs = service.queryJobDefinitions(handle, null, QueryField.NAME, true); Enumeration<MetadataObjectId> jobSets = service.queryJobSets(handle, null, QueryField.NAME, true); Enumeration<MetadataObjectId> schedules = service.querySchedules(handle, null, QueryField.NAME, true); Enumeration<MetadataObjectId> jobTypes = service.queryJobTypes(handle, null, QueryField.NAME, true); return new MetadataLists(jobDefs, jobSets, schedules, jobTypes); } }; MetadataLists ml = performOperation(myPayload, logger); return ml; } private RuntimeLists getRuntimeLists() throws Exception { Logger logger = getLogger(); RuntimeServicePayload<List<RequestDetail>> myPayload2 = new RuntimeServicePayload<List<RequestDetail>>() { @Override List<RequestDetail> execute(RuntimeService service, RuntimeServiceHandle handle, Logger logger) throws Exception { List<RequestDetail> reqDetails = new ArrayList<RequestDetail>(10); Enumeration requestIds = service.queryRequests (handle, null, RuntimeService.QueryField.REQUESTID, true); while (requestIds.hasMoreElements()) { Long reqId = (Long)requestIds.nextElement(); RequestDetail detail = service.getRequestDetail(handle, reqId); reqDetails.add(detail); } return reqDetails; } }; List<RequestDetail> reqDetails = performOperation(myPayload2, logger); RuntimeLists rl = getRuntimeLists(reqDetails); return rl; } private RuntimeLists getRuntimeLists(List<RequestDetail> reqDetails) { Set<String> applicationSet = new HashSet<String>(10); Set<String> stateSet = new HashSet<String>(10); Set<MetadataObjectId> jobDefMOSet = new HashSet<MetadataObjectId>(10); if (reqDetails != null) { ListIterator detailIter = reqDetails.listIterator(); while (detailIter.hasNext()) { RequestDetail detail = (RequestDetail)detailIter.next(); applicationSet.add(detail.getDeployedApplication()); State state = detail.getState(); if (state.isTerminal()) stateSet.add(state.name()); jobDefMOSet.add(detail.getJobDefn()); } } RuntimeLists rl = new RuntimeLists (reqDetails, applicationSet, stateSet, jobDefMOSet); return rl; } }
You need to edit the web.xml
file to and Oracle Enterprise Scheduling Service metadata and runtime EJB references.
To edit the web.xml file for the front-end submitter application:
In the Application Navigator, expand SuperWeb, expand Web Content, expand WEB-INF and double-click web.xml.
In the overview editor, click the References navigation tab and expand the EJB References section.
Add two EJB resources with the information shown in Table 5-1.
Click the Servlets navigation tab and click the Servlet Mappings tab.
Change the /essdemoappservlet
URL pattern to /essdemoappservlet/*
.
You need to create and edit the weblogic-application.xml file.
To edit the weblogic-application.xml file for the front-end submitter application:
In Application Navigator, right-click the SuperEss project and select New.
In the New Gallery, expand General, select Deployment Descriptors and then Weblogic Deployment Descriptor, and click OK.
In the Select Descriptor page select weblogic-application.xml.
Click Next, click Next again, and click Finish.
In the source editor, replace the contents of the weblogic-application.xml
file that you just created with the XML shown in Example 5-12.
Example 5-12 Contents to Copy to weblogic-application.xml for a Front-End Submitter Application
<?xml version = '1.0' encoding = 'UTF-8'?> <weblogic-application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-application http://www.bea.com/ns/weblogic/weblogic-application/1.0/weblogic-application.xsd" xmlns="http://www.bea.com/ns/weblogic/weblogic-application"> <!-- The following application parameter tells JPS which stripe it should - use to upload the jazn-data.xml policy. If this parameter is not - specified, it will use the Java EE deployment name plus the version - number (e.g. EssDemoApp#V2.0). --> <application-param> <param-name>jps.policystore.applicationid</param-name> <param-value>EssDemoAppUI</param-value> </application-param> <!-- This listener allows JPS to configure itself and upload the - jazn-data.xml policy to the appropriate stripe --> <listener> <listener-class>oracle.security.jps.wls.listeners.JpsApplicationLifecycleListener</listener-class> </listener> <!-- This listener allows MDS to configure itself and upload any metadata - as defined by the MAR profile and adf-config.xml --> <listener> <listener-class>oracle.mds.lcm.weblogic.WLLifecycleListener</listener-class> </listener> <!-- This listener allows Oracle Enterprise Scheduling Service to configure itself --> <listener> <listener-class>oracle.as.scheduler.platform.wls.deploy.ESSApplicationLifecycleListener</listener-class> </listener> <!-- This shared library contains all the Oracle Enterprise Scheduling Service classes --> <library-ref> <library-name>oracle.ess.client</library-name> </library-ref> <library-ref> <library-name>adf.oracle.domain</library-name> </library-ref> </weblogic-application>
You need to edit the adf-config.xml file to tell the application to share the metadata that was created in the hosting application.
To edit the adf-config.xml file for the front-end submitter application:
From the Application Resources panel, expand Descriptors, expand ADF META-INF, and double-click adf-config.xml.
In the source editor, replace the contents of the adf-config.xml
file with the XML shown in Example 5-13.
Example 5-13 Contents to Copy to adf-config.xml for a Front-End Submitter Application
<?xml version="1.0" encoding="UTF-8" ?> <adf-config xmlns="http://xmlns.oracle.com/adf/config"> <adf-security-child xmlns="http://xmlns.oracle.com/adf/security/config"> <JaasSecurityContext initialContextFactoryClass="oracle.adf.share.security.JAASInitialContextFactory" jaasProviderClass="oracle.adf.share.security.providers.jps.JpsSecurityContext" authorizationEnforce="false" authenticationRequire="true"/> </adf-security-child> <adf-mds-config xmlns="http://xmlns.oracle.com/adf/mds/config"> <mds-config xmlns="http://xmlns.oracle.com/mds/config" version="11.1.1.000"> <persistence-config> <metadata-namespaces> <namespace metadata-store-usage="ess_shared_metadata" path="/oracle/apps/ess/howto"/> </metadata-namespaces> <metadata-store-usages> <metadata-store-usage default-cust-store="false" deploy-target="false" id="ess_shared_metadata"/> </metadata-store-usages> </persistence-config> </mds-config> </adf-mds-config> </adf-config>
After you create the front-end sample application you use Oracle JDeveloper to assemble the application.
To assemble the back-end application you do the following:
Create the EJB Java Archive
Create the WAR file
Create the application MAR and EAR files
The EJB Java archive file includes descriptors for the Java job implementations.
To assemble the EJB JAR File for the front-end submitter application:
In Application Navigator, right-click the SuperEss project and choose New.
In the New Gallery, expand General, select Deployment Profiles and then EJB JAR File, and click OK.
In the Create Deployment Profile dialog, set the Deployment Profile Name to JAR_SuperEssEjbJar
.
On the Edit EJB JAR Deployment Profile Properties dialog, click OK.
On the Project Properties dialog, click OK.
You need to create a web archive file for the web application.
To assemble the WAR file for the front-end submitter application
In Application Navigator, right-click the SuperWeb project and choose New.
In the New Gallery, expand General, select Deployment Profiles and then WAR File, and click OK.
In the Create Deployment Profile dialog, set the Deployment Profile Name to WAR_SuperWebWar
.
On the Edit WAR Deployment Profile Properties dialog, click the General navigation tab, select Specify Java EE Web Context Root, and enter ESSDemoApp
.
Click OK.
On the Project Properties dialog, click OK.
The sample application needs to contain the MAR profile and the EAR file that assembles the back-end application.
To create the MAR and EAR files for the front-end submitter application:
From the main menu, choose Application Menu > Application Properties...
In the Application Properties dialog, click the Deployment navigation tab and click New.
In the Create Deployment Profile dialog, select MAR File from the Archive Type dropdown list.
In the Name field, enter MAR_EssDemoAppUIMar
and click OK.
Click OK.
In the Deployment page of the Application Properties dialog, click New.
In the Create Deployment Profile dialog, select EAR File from the Archive Type dropdown list.
In the Name field, enter EAR_EssDemoAppUIEar
and click OK.
In the Edit EAR Deployment Profile dialog, click the General navigation tab and enter EssDemoAppUI
in the Application Name field.
Click the Application Assembly navigation tab, then select MAR_ESSDemoAppUIMar
and select JAR_SuperEssEjbJar
.
Click OK.
In the Application Properties dialog, click OK.
After assembling the application, you can deploy it to the server.
To deploy the back-end hosting application:
From the main menu, choose Application > Deploy > EAR_EssDemoAppEar...
Set up and deploy the application to a container.
On the Deployment Configuration dialog, there should be two entries in the Shared Metadata Repositories panel. Find the shared repository mapped to the /oracle/apps/ess/howto namespace
. Change its partition to the partition used when deploying EssDemoApp
. If you used the default value, this should be EssDemoApp_V2
.0.
Click OK.