How To Use Multiple Struts Configurations With JDeveloper 10 g

An Oracle JDeveloper How To Document
Duncan Mills
January 2004

Content

      Introduction
      JDeveloper 10g and Multiple Configurations
      Creating a new Multiple Configuration Workspace
      Creating a Working Multiple Configuration Workspace from an Existing WAR file
      Running Child Application Page flows
      Conclusion

Introduction

This document discusses how you can set up a JDeveloper 10 g workspace in order to use the multiple configuration features of Apache Struts. The use of multiple configuration files for the same application is a new feature added to Struts version 1.1 to help application developers better structure their sites and to ease the burden of maintenance for large applications. Multi configuration actually encompasses two different styles of usage:

  • Peer configurations - where one large application struts-config.xml file has been arbitrarily split up into two or more peer configuration files. The struts-example application is an example of this.
        <servlet>
          <servlet-name>action</servlet-name>
                                      
    
          <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
                                      
    
          <init-param>
                                      
    
             
                                       <param-name>config</param-name>
                                      
    
             
                                       <param-value>/WEB-INF/struts-config.xml, /WEB-INF/struts-config-registration.xml</param-value>
                                      
    
          </init-param>
                                      
    
          ...
                                      
    
        </servlet>
                                    
  • Sub-applications - where a more logical division of an application exists and where there is a master application configuration file and then one or more sub-application configuration files which are children of the main application and accessed at runtime using a path like syntax based on the sub-application name..
        <servlet>
          <servlet-name>action</servlet-name>
                                      
    
          <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
                                      
    
         <init-param>
                                      
    
            <param-name>
                                       config</param-name>
                                      
    
            <param-value>
                                       /WEB-INF/struts-config.xml</param-value>
                                      
    
         </init-param>
         <init-param>
                                      
    
            <param-name>
                                       config/child1</param-name>
                                      
    
            <param-value>
                                       /WEB-INF/child1-config.xml</param-value>
                                      
    
         </init-param>
         <init-param>
                                      
    
            <param-name>
                                       config/child2</param-name>
                                      
    
            <param-value>
                                       /WEB-INF/child2-config.xml</param-value>
                                      
    
         </init-param>
                                      
    
          ...
                                      
    
        </servlet>
                                    

This document assumes that you are already familiar with the basic use of Struts, Struts multiconfig usage and of JDeveloper 10g as a Struts development environment.

JDeveloper 10 g and Multiple Configurations

The reason for producing this document is to help developers around a restriction in the initial release of the JDeveloper 10 g product. With this release of the product only one Struts page flow diagram can exist in each project. Attempting to use multiple page flow diagrams within a project can lead to unpredictable results and diagram corruption. As a result, applications which want to utilize peer or sub configurations will need to be organized in a special way to allow full page flow diagram functionality for each configuration file. The exact steps are outlined below, both for new applications and existing applications.

Creating a new Multiple Configuration Workspace

When creating a new multi config application you will need to plan in advance how many configuration files you will be using. In this example we'll use a total of three configurations, struts-config.xml as the parent configuration and two sub applications child1-config.xml and child2-config.xml. The principals of maintaining this projects in sync revolve around the use of a common HTML root and a common J2EE application name shared by all the projects. So lets step through the creation process for our workspace.

  1. Starting with an existing workspace or a newly created on if required, create three empty projects, in this case called parent, child1 and child2. It is best to create all of these under a common workspace directory, with each project in it's own sub-directory.
  2. At the same level as each of the project directories in the file system, create a public_html directory so you end up with a directory structure as follows:
    • Workspace directory
      • Parent
      • Child1
      • Child2
      • public_html
  3. Now edit the project properties of each project. Under the Common >> Input Paths node of the project properties, set the HTML Root Directory property to point to the common public_html directory
  4. Also in the project properties, choose the Common >> J2EE node and set each of the projects to use the same application and context root names e.g. multiApp and multiApp-context-root respectively. As you set the second and subsequent projects to share the same J2EE information you will receive a warning that another project shares the same name, you can ignore this warning and press Yes to continue.
  5. At this point save the workspace.
  6. Now you need to add Struts and your chosen view technology to the technology scope of each project. It is important that you do this to the parent project last.
    Again from the project properties dialog choose Common >> Technology Scope. Shuttle Struts and your view technology (e.g. JavaServer Pages (JSP) and Servlets) into the selected technologies list. When you OK the project properties dialog you will see a few files have been added to the project. Now save the Workspace. It is important to rename the struts-config.xml to the required name in each project as you go. So rename the xml file using File >> Rename, then save the workspace again and then continue to the next project.
  7. Once all of the projects have been set up for Struts you will need to edit the web.xml to define how each of the configurations will be used. As all of the projects share the same HTML root directory, they will also be sharing the same web.xml. As a result you have to be careful when updating web.xml and it is advisable to only ever update it from one place e.g. the parent project in this case. In this example we have three configurations, two of which are sub-applications. Here is the relevant part of the example web.xml file:
    <?xml version = '1.0' encoding = 'windows-1252'?>
                                      
    
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://bit.ly/bnsLU6">
                                      
    
    <web-app>
                                      
    
       <description>Empty web.xml file for Web Application</description>
                                      
    
       <servlet>
                                      
    
         <servlet-name>action</servlet-name>
                                      
    
         <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
                                      
    
         <init-param>
                                      
    
            <param-name>
                                       config</param-name>
                                      
    
            <param-value>
                                       /WEB-INF/struts-config.xml</param-value>
                                      
    
         </init-param>
         <init-param>
                                      
    
            <param-name>
                                       config/child1</param-name>
                                      
    
            <param-value>
                                       /WEB-INF/child1-config.xml</param-value>
                                      
    
         </init-param>
         <init-param>
                                      
    
            <param-name>
                                       config/child2</param-name>
                                      
    
            <param-value>
                                       /WEB-INF/child2-config.xml</param-value>
                                      
    
         </init-param>
                                      
    
    ...
                                    

    This Struts application is set up then with two sub applications which will be accessed through the use of /child1/ and /child2/ in the URI.
  8. Next you will need to flag to the projects that they are all dependent on each other - this is important to ensure that all of the files are correctly deployed when it comes to running your application and for resolving common files such as a shared ApplicationResources.properties file. Again this is done through the project properties dialog using the Common >> Dependencies node.
  9. Finally when it comes to running the application, ensure that you run the parent project first. Running an action on one of the child configurations before the parent can cause the parent not to run subsequently, although this can be corrected by changing the J2EE application and context root names in all of the projects and rerunning the parent project

Creating a Working Multiple Configuration Workspace from an Existing WAR file

If you have an existing code base or application which uses multiple configurations which you want to edit through JDeveloper you can import a WAR file of the application into an empty JDeveloper Workspace using the following steps :

  1. In the Application Navigator create an empty workspace, uncheck the Create New Empty Project checkbox if this is set.
  2. Select the workspace and choose File -> Import.
  3. In the Import dialog select the WAR file file you wish to consume. The Create Project from War File Wizard will appear.
  4. In step 1 define the project name as required and it's location. (Bear in mind that like starting from scratch you will be creating several projects to hold the various configurations).
  5. In step 2 of the wizard, define the name of the WAR file that you wish to import and define the location for the HTML root. As in the custom created projects, this HTML Root will be shared so it's probably a good idea to define it at the same level as your imported project, rather than under the imported project directory itself.
  6. Once the WAR file is imported expand the project WEB-INF folder. Examine the web.xml file to see which is the primary Struts configuration in the servlet definition, you'll want to keep this primary XML file in this project and move any others into projects of their own. So in the case of the struts-example.war that is shipped as a sample with Struts, and available in the /jakarta-struts/webapps directory under the JDeveloper distribution, the configuration setting in the web.xml looks like this:
      <!-- Action Servlet Configuration -->
                                      
    
      <servlet>
                                      
    
        <servlet-name>action</servlet-name>
                                      
    
        <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
                                      
    
        <init-param>
                                      
    
          <param-name>config</param-name>
                                      
    
          <param-value>/WEB-INF/struts-config.xml, /WEB-INF/struts-config-registration.xml</param-value>
                                      
    
        </init-param>
                                      
    
        <load-on-startup>1</load-on-startup>
                                      
    
      </servlet>
                                    
  7. So in this case the struts-config.xml should remain in the import project and the struts-config-registration.xml removed from the import project using the remove button or the remove option on the file menu (not it needs to be removed from the project but not deleted from disk)..
  8. Create a new empty project for each of the extra configuration files.
    For each file:
    • In the project properties dialog select the Common -> Input Paths node of the tree and set the HTML Root Directory to the top level HTML Root directory you defined when using the WAR import wizard
    • The select the Common -> Dependencies node in the preferences dialog and check the dependency to the project imported from the WAR file.
    • Then select the Common -> J2EE node in the preferences dialog and set both the J2EE Web Application Name and the J2EE Web Context Root to the same values as used by the project imported from the WAR file. Ignore the unique name warning that pops up.
    • Then select the libraries node of the project properties tree and add JSP Runtime and Struts Runtime to the selected libraries list.
    • Choose Add to ... from the file menu to add the existing web.xml and secondary Struts configuration file to the new project
    • Back in the imported project edit the project properties and add this new project as a dependency of the imported one.

Once you have completed this process for each sub configuration you will be able to open a page flow diagram up in each project. You may choose to move JSP files etc to the relevant project that they apply to, however, there is no need to specifically do this as JDeveloper will work out where the files are if you try and drill down into them from the page flow diagram.

Running Child Application Page Flows

In the situation where you have sub-applications (such as in our example child1 and child2), you will be able to run Actions on the parent page flow diagram, or any peer application of the parent directly. However, if you attempt to run an Action from a sub application page flow diagram, it will fail with HTTP 400 (page cannot be found) error. This is because the URL that the runner will construct for the Action will not include the sub application path. For instance the url: http://localhost:8988/multiApp-context-root/child1_index.do may be generated rather than the correct http://localhost:8988/multiApp-context-root /child1 /child1_index.do.

There are several approaches you can take to making it possible to run from a child application diagram. Take the situation where the parent project has a single entry point that the user always has to traverse, for instance a logon page. In this case using the context menu on the parent diagram set that page as the default run target for the parent diagram. This has the side effect of setting the Action unknown attribute to true for that action, so if you run from any of the other diagrams where an invalid Action URL is generated, Struts will redirect you to the application start point automatically.

Note that this will only work successfully if your Action names are unique across all of the sub applications.

However, you may wish to unit test just the flow within a particular sub application. If this is the case then you will need to adopt the following procedure.

  1. In the child configuration project, create a new JSP page called launch.jsp or similar.
  2. Edit this new page and add the following tag to the body:
    <jsp:forward page="/child1/child1_index.do"/>
    (Change the sub-application path and entry action as appropriate for your application)
  3. Edit the project properties for the child application project and in the Profiles >> Runner settings set the Default Run Target to your launch JSP and uncheck the Attempt to Run Active File Before Default checkbox.
  4. Now when you select run from the diagram this launch page will run, which in turn will construct the correct URL for your sub app.
  5. If you need to test different Actions within the child application, simply update the <jsp:forward> tag on this launch page as required.

Conclusion

Although the initial release of JDeveloper 10 g does not seamlessly support multiple configuration Struts applications, with a little care it is entirely possible to use the product with such applications. In the next version of JDeveloper 10 g it will be possible to dispense with the multiple project requirement, although structuring the workspace in this way may have benefits if multiple developers are working on different sections of the application.

drmills v1.1 13-Jan-2004

false ,,,,,,,,,,,,,,,