X

Technical Articles relating to Oracle Development Tools and Frameworks

  • JET
    July 21, 2020

Creating a WAR file for your JET Application

Duncan Mills
Architect

Introduction

A common question we get is how to bundle up a built JET project into a WAR file for deployment into a server such as WebLogic or Tomcat.  This is easy to achieve using the available build hooks provided by the ojet cli tool.

Setup 

In order to create the WAR archive you'll need the archiver package used to create the WAR file and the fs-extra package that is used in the example hook to ensure that the output directory exists before we attempt to write to it.  Both of these packages are included as a by product of installing the @oracle/ojet-cli package, but it's a good idea to be explicit for future maintainability and install them. Use the following commands from the root of your JET project 

npm install archiver --save-dev
npm install fs-extra --save-dev

Next decide on your output folder - I've used dist in the example here. Add that to your .gitignore file so that you don't end up checking in the generated WAR file.

The Build Hook

Now we can define the hook.  You will find a skeleton after_build.js hook file in the /scripts/hooks folder. Update it as follows:

/**
  Copyright (c) 2015, 2020, Oracle and/or its affiliates.
  Licensed under The Universal Permissive License (UPL), Version 1.0
  as shown at https://oss.oracle.com/licenses/upl/

*/

'use strict';

const fs = require('fs-extra');
const path = require('path');
const archiver = require('archiver');

module.exports = function (configObj) {
  return new Promise((resolve, reject) => {
    console.log('Running after_build hook.');
    if (configObj.buildType==='release'){
      console.log('Packaging WAR file for deployment'); 

      //Ensure that the output folder exists, create it if not
      const distributionFolder = 'dist'
      fs.ensureDirSync(distributionFolder);

      // Define the name for the WAR file based on the package name / version defined 
      // in package.json (or you could hardcode!)
      const packageInfo = fs.readJSONSync('package.json');
      const warFile = path.join(distributionFolder,`${packageInfo.name}-${packageInfo.version}.war`);

      // Read the JET configuration file to work out what folder to archive
      // This is /web by default but it might have been configured as something else
      const jetConfig = fs.readJSONSync('oraclejetconfig.json');
      const webRoot = jetConfig.paths.staging.web;

      // Create the archiver - a WAR file is just a ZIP
      const output = fs.createWriteStream(warFile);
      const archive = archiver('zip');
      
      // Archiver Callbacks
      output.on('close', () => {
        console.log('Files were successfully packaged into WAR file');
      });
 
      archive.on('warning', (warn) => {
        console.warn(`Warning when packaging WAR file: ${warn}`);
      });
 
      archive.on('error', (error) => {
        console.error(`Error when packaging WAR file: ${error}`);
      });
 
      // And start the archive process 
      archive.pipe(output);
      archive.directory(webRoot, false);
      archive.finalize();
    }
  
    // The archiving process (if it takes place) can be asynchronous 
    // so we return can control to the CLI immediately
  	resolve(configObj);
  });
};

You'll notice that I only invoke the WAR file generation if you do a ojet build --release in this example, that's up to you of course. Finally I've not discussed any descriptor files that your web server might require (e.g. web.xml).  The need for those will depend on your server and it's configuration.  If they are required then as long as they are under your /src folder then then will be copied into /web and deployed into the .war file

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.