DOAG DevCamp2016: Oracle Development Cloud Service Hands On by Timo Hahn (Part 3)
In part two of the series we have moved the source of the application to the DCS GIT repository and covered the agile development capabilities of the Oracle Development Cloud Service. In this final part we show how to setup the continuous build service for the application.

To build the application in the DCS we have to create ANT build files or a Maven pom. We use ANT to build the project. To create a starting set of ANT build files we can use JDeveloper (New->Ant->BuildScript from Application). This will create two files, build.xml and build.properties. The build.xml file is the ANT build file and is not dependent on the environment. All environment dependent variables are put in the build.properties file. A sample of the created build properties look like

#Mon Feb 15 21:29:41 CET 2016
oracle.commons=R\:\\Java\\12.1.3.0.0\\Oracle\\Middleware\\oracle_common
install.dir=R\:\\Java\\12.1.3.0.0\\Oracle\\Middleware
oracle.jdeveloper.ant.library=R\:\\Java\\12.1.3.0.0\\Oracle\\Middleware\\jdeveloper\\jdev\\/lib/ant-jdeveloper.jar
oracle.home=R\:\\Java\\12.1.3.0.0\\Oracle\\Middleware\\jdeveloper
oracle.jdeveloper.workspace.path=Q\:\\JavaDevCloud\\DOAGDEVCAMP2016\\AppsCloudUIKit\\AppsCloudUIKit.jws
oracle.jdeveloper.deploy.profile.name=*
oracle.jdeveloper.deploy.dir=Q\:\\JavaDevCloud\\DOAGDEVCAMP2016\\AppsCloudUIKit\\deploy
oracle.jdeveloper.ojdeploy.path=R\:\\Java\\12.1.3.0.0\\Oracle\\Middleware\\jdeveloper\\jdev\\bin\\ojdeploy.exe
oracle.jdeveloper.deploy.outputfile=Q\:\\JavaDevCloud\\DOAGDEVCAMP2016\\AppsCloudUIKit\\deploy\\${profile.name}

We see that the generated properties are holding absolute path variables to programs like ojdeploy or the installation path of your local JDeveloper. We can use these two files to build the application locally without a problem. Working with the same properties, the absolute path variables, in the DCS will not work. The path from the local machine simply does not exist on the server. We need to make some changes to the properties file.

The goal is to use the ant build.xml and build.properties file in both environments with minimal changes. The less we lees to change the better. JDeveloper did some good ground work for us. The build.xml file have no dependency to the environment it’s running at. The save build.xml file can be used to run on the local environment and any server. All locations are either relative or are addressed with properties from the build.properties file.

The DCS offers two different environments (today), one for version 11.1.1.7.0 and one for version 12.1.3.0.0. The environments can be used by using environment variables which are preset for the server which is running the DCS. There are two ORACLE_HOME variables predefines env.ORACE_HOME_11G7 and env.ORACLE_HOME_12C3. Depending on which JDeveloper version we use to develop an application and which runs on the server we substitute the absolute path by one of the preset environment variables:

oracle.commons=R\:\\Java\\12.1.3.0.0\\Oracle\\Middleware\\oracle_common

changed to

oracle.commons=${env.ORACLE_HOME_12C3}\oracle_common =${env.ORACLE_HOME_12C3}

This we have to do with all absolute path variables we find in the build.properties file. We don’t even have to know the real path of the installation on the DCS, all we do is to use the predefined environment variables. Another thing to take care of is that the Hudson server which uses the build files run on a Linux machine whereas we normally use a Windows machine. In case that you run rue local development on a Linux machine too, you can skip the next paragraph.

Use the same build.xml and build.properties on Windows and Linux machines

There are some small but vital differences when running the development on Windows against running it on Linux.

  1. The path separator is different: ‘/’ in Linus, ‘\’ in windows
  2. Executables in windows have a suffix ‘.exe’

It would make sense to use the same build files on both machines. The path separator isn’t much of a problem as the ant tool manages reading Windows and/or Linux without a problem. To make the path separator work on both machines we use the Linux version in the build.properties. This can be done by a simple search and replace job.

The build properties contain one call to an executable ojdeploy. This is the packaging task JDeveolper uses to build jar, war and ear files. The name suggests that its use is to deploy something to a server, but that’s not what’s ojdeploy is doing. The problem is that Windows uses a suffix ‘.exe’ for executables, whereas Linux does not. Here an executable just has a flag set on the file properties. One solution would be to rename the ojdeploy on the Linux side to ‘ojdeploy.exe’, but for this we have to have access to the servers file system and the right to change this setting.  We use a property which we define for the ant build job, ‘${env.EXEC_SUFFIX}’. The trick is to set the ‘${env.EXEC_SUFFIX}’ property to ‘.exe’ on a windows system and to ‘’ (empty) on a Linux system.

On a Windows machine we define a system property for this

1

On a Linux local system we can use an export command. For the Hudson build we use an ant property

2

Optimizing the build.properties for reuse

A close inspection of the original build.properties file shows, that we only need five properties to make the build.properties easy to handle for every project which we want to develop in the cloud and on a local environment.

  • name: holds the name of the workspace, in our case AppsCloudUIKit
  • viewcontroller.name: holds the name of the view controller project which is used to build the WAR file. The sample application uses the ‘DemoMaster’ project to create the WAR file.
  • deploy.folder: holds the folder where all artefacts are stored. This folder holds the final artefact, the EAR file.
  • jdeveloper.deploy.profile.name: The name of the application profile which builds the EAR file.
  • dir: holds the directory the build process uses to put the class files to.

The remaining properties don’t change as they use environment variables which will be set by the machine the build system is running on. In the cloud we have two environments (at the time of writing), one for 11g (11.1.1.7.1) and one for 12c (12.1.3). We use the 12.1.3 environment as our JCS uses 12.1.3 too.

The main environment variables are ‘${env.ORACLE_HOME_12C3}’, ‘${env.MIDDLEWARE_HOME_12C3}’, ‘${env.WORKSPACE}’ and finally ‘${env.EXEC_SUFFIX}’. All of them start with ‘env.’ which shows that they are read from the environment. To make ant aware of the environment variables we have to add one line to the generated build.xml at the beginning of build.xml

<property environment="env" />

3

The final version can be seen below or downloaded at Ant build.properties

#Change the next properties to match your projects names
workspace.name=AppsCloudUIKit
project.viewcontroller.name=DemoMster
project.deploy.folder=deploy
oracle.jdeveloper.deploy.profile.name=AppsCloudUIKit
output.dir=classes

# Don’t change anything below!
oracle.home=${env.ORACLE_HOME_12C3}
oracle.commons=${env.MIDDLEWARE_HOME_12C3}/oracle_common
middleware.home=${env.MIDDLEWARE_HOME_12C3}
install.dir=${env.ORACLE_HOME_12C3}

#Flags
javac.deprecation=off
javac.nowarn=off
java.debug=on

project.workspace.file=${workspace.name}.jws
oracle.jdeveloper.ant.library=${oracle.home}/jdev/lib/ant-jdeveloper.jar
oracle.jdeveloper.workspace.path=${env.WORKSPACE}/${workspace.name}.jws
oracle.jdeveloper.project.name=${project.viewcontroller.name}
oracle.jdeveloper.deploy.dir=${env.WORKSPACE}/${project.deploy.folder}
oracle.jdeveloper.ojdeploy.path=${env.ORACLE_HOME_12C3}/jdev/bin/ojdeploy${env.EXEC_SUFFIX}
oracle.jdeveloper.deploy.outputfile=${env.WORKSPACE}/${project.deploy.folder}/${oracle.jdeveloper.deploy.profile.name}

Setting up the Build Job in the DCS

The next task it to set up the build job in the DCS. For this we create a new job

4

Give the job a name and can now select to create a new job or to copy an existing one. We select to create a new one

5

Now we configure the build job by filling in the needed information. On the main tab we can describe the job, decide which JDK to use and how many build job executions are saved. If you use a high number the space on your virtual storage is filling up quickly as all output and all artefacts are stored. We set this to 10.

6

We skip the next tab ‘Build Parameters’ and move to the ‘Source Control’ tab

7

As we use Git, we set the radio button to Git and select the repository of the project we want to build. The ‘Advanced Repository Settings’ are set automatically. In the ‘Branch Specifier’ field we can tell which branch we want to check out. Next we tell the build system when to start working

8

Here we select that we want to poll the source control system every minute for changes. The schedule uses the Linux ‘cron’ syntax. We skip the ‘Environment’ tab and define one build step on the ‘Build Steps’ tab

9

All we need to do is to execute the Appbuild.xml target ‘deploy’. This will compile all other needed projects and create the needed jars before finally creating the applications ear file. The remaining tab we leave unchanged and save the job configuration. In the ‘Properties’ field we see the definition of the ${env.EXEC_SUFFIX} variable mentioned before.

10

The ‘Post Build’ tab defines what to do with the outcome of the build. Here we define that the generated artifacts which end up in the ‘deploy’ folder should be archived in GZIP format. If we don’t do this the build runs but as nothing is saved, we later can’t deploy the ear file. The remaining tab ‘Advanced we skip and save the created job.

Now we can run the build job by clicking the ‘Build’ button. The job doesn’t start immediately but is queued first, then starts running.

11

… when the build starts we see the change in status.

12

We can look at the console output of the job by clicking the console icon of the running job. If you click on the console icon of a finished job you see the complete output.

13

Once the job has finished successfully the artifacts are shown with the build.

14

In the next and final part we see how to setup the ‘Continuous Integration’ part by deploying the application to the JCS.

Timo Hahn