Friday, August 12, 2016

Automating deployments to WebLogic with weblogic-maven-plugin and certificates

Abstract

So you use WebLogic. You also have continuous integration running (Bamboo, Jenkins, etc.) It would be nice to incorporate continuous deployments, and have deployments automated too. But how do you automate deployments from your CI build servers to your WebLogic servers? You may think, there’s a Maven plugin for that, and you’d be right! You might also think, “I can search Maven central, find the latest version of the plugin, and drop it into my POM.” If you have this thought, you’d be wrong! A Maven plugin does exist, but it’s unlike any Maven artifact you’ve ever used. This article describes in detail how to use weblogic-maven-plugin for continuous deployments. To do this, you’ll need to perform the following steps:

  1. Download, install, and configure WebLogic
  2. Create a WebLogic domain, which also automatically creates an admin server for the domain.
  3. Install the WebLogic crypto libraries into your Maven repository
  4. Generate the WebLogic config/key files and install them into your Maven repository
  5. Generate the WebLogic weblogic-maven-plugin.jar file and install it into your Maven repository.
  6. Add all the configuration to your project’s pom.xml to get weblogic-maven-plugin working.

Requirements

These are the version of the major pieces of software I used. No guarantees this will work if you use different versions.

  • WebLogic 10.3.6
  • Java 1.6.0_23
  • Maven 3.0.5

NOTE This article describes how to generate weblogic-maven-plugin using WebLogic 10.3.6. This plugin will work with 10.3.x version of WebLogic but the plugin has also successfully worked with WebLogic 12.1.3.

WebLogic

Download

Download WebLogic from the Oracle WebLogic Server Installers page. There are many different versions and file formats available to download. This article uses the ZIP format of version 10.3.6. So make sure you download the following:

  • Version 10.3.6
  • The Zip distribution named “- Zip distribution for Mac OSX, Windows, and Linux (183 MB)”

NOTE You will need an Oracle account to download.

After you have downloaded the ZIP file, you’ll need to unzip it. Unzipping is a piece of cake right? Not so fast. There can be a number of problems unzipping this file. Let’s take a look at unzipping next.

Unzip

Unzipping the WebLogic ZIP distribution can be a bit of a challenge. Both WinZip and 7-Zip gave errors on Windows. So you are better off using the Java jar command to unzip the file. Let’s do that now.

C:\>set JAVA_HOME=C:\Applications\Java\jdk1.6.0_20\x64
C:\>set PATH="%JAVA_HOME%\bin";%PATH%
C:\>cd C:\Applications
C:\>mkdir wls1036
C:\>cd wls1036
C:\Applications\wls1036>jar xvf C:\Users\Michael\Downloads\wls1036_dev.zip

When you are done, the wls1036 directory will look like this:

C:\Applications\wls1036>dir
 Volume in drive C is OS

 Directory of c:\Applications\wls1036

08/09/2016  10:51 AM    <DIR>          .
08/09/2016  10:51 AM    <DIR>          ..
11/15/2011  11:23 AM             1,421 configure.cmd
11/15/2011  11:23 AM             1,370 configure.sh
11/15/2011  11:23 AM             3,189 configure.xml
11/15/2011  11:23 AM               133 domain-registry.xml
11/15/2011  11:23 AM    <DIR>          modules
11/15/2011  11:23 AM             5,765 README.txt
11/15/2011  11:23 AM             1,138 registry.template
11/15/2011  11:23 AM    <DIR>          utils
11/15/2011  11:23 AM    <DIR>          wlserver
               6 File(s)         13,016 bytes
               5 Dir(s)  60,949,000,192 bytes free

Now that WebLogic has been unzipped, let’s look at its configuration next.

Configure

Simply execute configure.cmd that comes with WebLogic.

NOTE If you are prompted to create a new domain, DO NOT do so.

C:\>set JAVA_HOME=C:\Applications\Java\jdk1.6.0_20\x64
C:\>set PATH="%JAVA_HOME%\bin";%PATH%
C:\>set MW_HOME=C:\Applications\wls1036
C:\>%MW_HOME%\configure.cmd

Next we will look at creating a new domain.

Create Domain

You will need a directory to hold your domains. Create this first.

C:\>cd \
C:\>mkdir Domains
C:\>cd Domains
C:\Domains>mkdir mydomain

Now you will need to execute a WebLogic command to create the domain. This command must be executed within the mydomain directory.

NOTE Use a simple username/password like mydomain/mydomain1. You can use the WebLogic admin console to change it later.

C:\>set JAVA_HOME=C:\Applications\Java\jdk1.6.0_20\x64
C:\>set PATH="%JAVA_HOME%\bin";%PATH%
C:\>set MW_HOME=C:\Applications\wls1036

C:\>%MW_HOME%\wlserver\server\bin\setWLSEnv.cmd

C:\>cd C:\Domains\mydomain

C:\Domains\mydomain>%JAVA_HOME%\bin\java.exe -Dweblogic.management.allowPasswordEcho=true -Xmx1024m -XX:MaxPermSize=128m weblogic.Server

When you are done, the mydomain directory will look like this:

C:\Domains\mydomain>dir
 Volume in drive C is OS

 Directory of C:\Domains\mydomain

08/09/2016  11:21 AM    <DIR>          .
08/09/2016  11:21 AM    <DIR>          ..
08/09/2016  11:21 AM    <DIR>          autodeploy
08/09/2016  11:21 AM    <DIR>          bin
08/09/2016  11:21 AM    <DIR>          config
08/09/2016  11:21 AM    <DIR>          console-ext
08/09/2016  11:21 AM               472 fileRealm.properties
08/09/2016  11:21 AM    <DIR>          init-info
08/09/2016  11:21 AM    <DIR>          lib
08/09/2016  11:21 AM    <DIR>          security
08/09/2016  11:17 AM    <DIR>          servers
08/09/2016  11:21 AM               283 startWebLogic.cmd
08/09/2016  11:21 AM               235 startWebLogic.sh
               3 File(s)            990 bytes
              10 Dir(s)  60,934,422,528 bytes free

Now that you have successfully created a domain, you can start the WebLogic admin server and use the console to administer the domain. Let’s take a look at that next.

Startup

Once WebLogic has been configured and a domain created, you can start the WebLogic admin server and login to the console. But first there’s a bug you have to deal with.

Fix WebLogic Bug

For some reason, when WebLogic creates the domain, the scripts it generates to start the domain fail to set the %MW_HOME% environment variable. So this is what you need to do.

  1. Open C:\Domains\mydomain\startWebLogic.cmd in your favorite text editor
  2. Add this line: set MW_HOME=C:\Applications\wls1036

Now you should be able to start the admin server for the domain.

Start WebLogic

Execute this command to start WebLogic.

C:\>cd C:\Domains\mydomain
C:\Domains\mydomain>startWebLogic.cmd

Login to Admin Console

Browse to the admin console, http://localhost:7001/console, and login with the simple credentials (mydomain/mydomain1) you set when you ran the command to create the domain.

Now that WebLogic is installed, configured, and up and running, let’s start generating the artifacts weblogic-maven-plugin will need, including the plugin itself. We’ll start with something easy, the crypto library.

Crypto Library

In order to automate deployments to WebLogic, at some point you will need to know the admin username and password for the WebLogic admin console. The weblogic-maven-plugin can be configured with a clear-text username and password, but that’s not a good idea. An alternative is to generate a key pair. The key pair allows access without the need for a clear-text password. When WebLogic generates this key pair, the data in the files are encrypted. The weblogic-maven-plugin will need the crypto library in order to decrypt. So, let’s get the crypto library into your Maven repository.

Install

The file we want to install in your Maven repository is C:\Applications\wls1036\modules\cryptoj.jar. The easiest way to do it is to use the mvn install:install-file command to put it into your Maven repository.

C:\>set JAVA_HOME=C:\Applications\Java\jdk1.6.0_20\x64
C:\>set PATH="%JAVA_HOME%\bin";%PATH%

C:\>set MAVEN_HOME=C:\Applications\NetBeans\NetBeans 8.1\java\maven
C:\>set PATH="%MAVEN_HOME%\bin";%PATH%

C:\>mvn install:install-file -DgroupId=com.oracle.cryptoj -DartifactId=cryptoj -Dversion=1.0.0.0 -Dpackaging=jar -Dfile=C:\Applications\wls1036\modules\cryptoj.jar

Check your .m2\repositories directory afterwords to verify it was installed successfully. Now we have the ability to decrypt data in key pair files. So the next thing to do is generate them.

Key Pair Files

To login to the WebLogic admin (web-based) console, you need to know the admin username and password. But the admin console is not the only way you can administer a WebLogic domain. WebLogic also has the WebLogic Scripting Tool (WLST), which is a command-line interface for administering a domain. Command-line interfaces are nice because they allow you to script your configuration process. But, an admin username and password are still needed when using the WLST. You can hard code clear-text usernames and passwords in scripts, but auditors and security teams don’t like that very much. As an alternative, WebLogic can generate encrypted config/key files. So, what we are going to look at next is:

  1. Generating the config/key files for a WebLogic domain
  2. Testing the the files (got to make sure they work before we try to use them for real)
  3. Installing the config/key files into a Maven repository (this isn’t technically necessary, but, it’s really nice when it comes to automating deployments. You’ll see this later)

Fix WebLogic Bug

Before you can proceed with generating the WebLogic config/key files, first you need to fix a WebLogic bug. The easiest way to execute WLST is to use the C:\Applications\wls1036\wlserver\common\bin\wlst.cmd command. However, for some reason this file is completely empty! If you find yourself with an empty wlst.cmd file, here are its contents.

@ECHO OFF
SETLOCAL    

SET MW_HOME=C:\Applications\wls1036
SET WL_HOME=%MW_HOME%\wlserver
CALL "%WL_HOME%\server\bin\setWLSEnv.cmd"

if NOT "%WLST_HOME%"=="" (
    SET WLST_PROPERTIES=-Dweblogic.wlstHome=%WLST_HOME% %WLST_PROPERTIES%
)

SET CLASSPATH=%CLASSPATH%;%FMWLAUNCH_CLASSPATH%;%DERBY_CLASSPATH%;%DERBY_TOOLS%;%POINTBASE_CLASSPATH%;%POINTBASE_TOOLS%

@echo.
@echo CLASSPATH=%CLASSPATH%

SET JVM_ARGS=-Dprod.props.file="%WL_HOME%\.product.properties" %WLST_PROPERTIES% %MEM_ARGS% %CONFIG_JVM_ARGS%

"%JAVA_HOME%\bin\java" %JVM_ARGS% weblogic.WLST %*

Now, let’s generate some config/key files!

Generate

Generating the config/key files is done with a few commands. The hardest part of running these commands is determining the correct values to pass to connect(). In the example below, localhost is used because this example was created using a personal laptop. On servers, especially VMs or machines with multiple network cards, you need to know what network interface WebLogic bound to when the admin server started. Typically, if you take the URL you use to browse to the admin console - http://localhost:7001/console - and edit it for WLST - t3://localhost:7001 - you’ll be OK. Let’s take a look at the commands.

C:\>set JAVA_HOME=C:\Applications\Java\jdk1.6.0_20\x64
C:\>set PATH="%JAVA_HOME%\bin";%PATH%
C:\>set MW_HOME=C:\Applications\wls1036

C:\>%MW_HOME%\wlserver\server\bin\setWLSEnv.cmd
C:\>%MW_HOME%\wlserver\common\bin\wlst.cmd

wls:/offline> connect('USERNAME','PASSWORD','t3://localhost:7001');

wls:/mydomain/serverConfig> storeUserConfig('C:\Users\Michael\Desktop\wls.config','C:\Users\Michael\Desktop\wls.key');

Now that you have the config/key files generated, let’s test them to make sure they work. It is always a good idea to test any key pair you generate for a domain before trying to use them in automated scripts. It makes troubleshooting issues easier.

Test

Test the config/key file by using the weblogic.Deployer application to get a list of all the applications deployed to the WebLogic domain. To do this, execute the following commands:

NOTE Make sure your WebLogic admin server is running before you try to test the config/key files.

C:\>set JAVA_HOME=C:\Applications\Java\jdk1.6.0_20\x64
C:\>set PATH="%JAVA_HOME%\bin";%PATH%
C:\>set MW_HOME=C:\Applications\wls1036

C:\>%MW_HOME%\wlserver\server\bin\setWLSEnv.cmd
C:\>java weblogic.Deployer -adminurl "t3://localhost:7001" -userconfigfile "C:\Users\Michael\Desktop\wls.config" -userkeyfile "C:\Users\Michael\Desktop\wls.key" -listapps

After executing the weblogic.Deployer application, the output will look similar to this:

weblogic.Deployer invoked with options:  -adminurl t3://localhost:7001 -userconfigfile C:\Users\Michael\Desktop\wls.config -userkeyfile C:\Users\Michael\Desktop\wls.key -listapps
There is no application to list.

C:\>

If you get this, congratulations! Your config/key files are working. Now let’s get these config/key files into your Maven repository. This will be similar to what you did for the crypto library. Let’s take a look.

Install

Let’s assume the config/key files are on your Desktop. To install them in your Maven repository the first thing you need to do is ZIP them up. The ZIP archive should look like figure 1.

Figure 1 - Zip archive of config/key files

Zip archive of config/key files
Zip archive of config/key files

After the ZIP file is created, use the use the mvn install:install-file command to put it into your computer’s local repository.

C:\>set JAVA_HOME=C:\Applications\Java\jdk1.6.0_20\x64
C:\>set PATH="%JAVA_HOME%\bin";%PATH%

C:\>set MAVEN_HOME=C:\Applications\NetBeans\NetBeans 8.1\java\maven
C:\>set PATH="%MAVEN_HOME%\bin";%PATH%

C:\>mvn install:install-file -DgroupId=com.oracle.weblogic.keys -DartifactId=localhost -Dversion=1.0.0.0 -Dpackaging=zip -Dfile=C:\Users\Michael\Desktop\Key.zip

-DgroupId and -DartifactId. The values for -DgroupId and -DartifactId are largely a detail up to you. When setting these values, keep in mind that you will be generating keys for every WebLogic domain that will be targets of automated deployments. So it’s a good idea to keep the values for -DgroupId and -DartifactId such that it’s easy to distinguish the environment and domain the keys are for.

-Dpackaging=zip. Don’t skip this value and note it’s value is zip. The majority of the time JAR files are put into a Maven repository, but this artifact is a ZIP.

NOTE Yes, I know that a JAR file and ZIP file are the same file format.

Check your .m2\repositories directory afterwords to verify it was installed successfully. With the key pair in the Maven repository, what’s next to do is to generate the weblogic-maven-plugin itself. Let’s do it.

Plugin JAR

At this point, you have installed the crypto libraries into your Maven repository (essential for decrypting the WebLogic config/key files) and you have generated the WebLogic config/key files (essential for eliminating clear-text usernames and passwords) and have also installed both of them into your Maven repository. Now let’s generate the plugin itself.

Generate

To generate weblogic-maven-plugin use the wljarbuilder tool and configure it to build the plugin. This tool comes with WebLogic and is located in wlserver\server\lib directory. Here are the commands to generate the plugin.

C:\>set JAVA_HOME=C:\Applications\Java\jdk1.6.0_20\x64
C:\>set PATH="%JAVA_HOME%\bin";%PATH%
C:\>set MW_HOME=C:\Applications\wls1036

C:\>cd %MW_HOME%\wlserver\server\lib
C:\Applications\wls1036\wlserver\server\lib>java -jar wljarbuilder.jar -profile weblogic-maven-plugin

This will run for a while. While it’s running, it will build an uber weblogic-maven-plugin.jar file. That’s it! That’s the plugin. Not too exciting is it? Well now you need to install the weblogic-maven-plugin.jar file into your Maven repository. That will be a little more exciting.

Install

Installing weblogic-maven-plugin into your Maven repository is pretty much the same as installing any other artifact. However, to make using the plugin easier, you need to update the plugin’s POM file before installing the plugin. Let’s do it.

Extract POM. Use the Java jar tool to extract the pom.xml file from weblogic-maven-plugin.jar. When you execute this command, the pom.xml file will be extracted in the same directory as weblogic-maven-plugin.jar.

C:\>set JAVA_HOME=C:\Applications\Java\jdk1.6.0_20\x64
C:\>set PATH="%JAVA_HOME%\bin";%PATH%
C:\>set MW_HOME=C:\Applications\wls1036

C:\>cd %MW_HOME%\wlserver\server\lib
C:\Applications\wls1036\wlserver\server\lib>jar xvf weblogic-maven-plugin.jar META-INF/maven/com.oracle.weblogic/weblogic-maven-plugin/pom.xml

Update POM. Now you want to update pom.xml and add a dependency on the crypto library. Remember, you installed the crypto library into the Maven repository earlier. Doing this makes weblogic-maven-plugin easier to use because Maven will automatically pull the crypto library out of the repository when the plugin needs to decrypt the WebLogic config/key files. Use your favorite text editor to open the C:\Applications\wls1036\wlserver\server\lib\META-INF\maven\com.oracle.weblogic\weblogic-maven-plugin\pom.xml file. Below you’ll see a piece of XML surrounded by the <!-- BEGIN --> and <!-- END --> comments. Copy what’s between these comments into your pom.xml.

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.oracle.weblogic</groupId>
  <artifactId>weblogic-maven-plugin</artifactId>
  <packaging>maven-plugin</packaging>
  <version>10.3.6.0</version>
  <name>Maven Mojo Archetype</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-plugin-api</artifactId>
      <version>2.0</version>
    </dependency>
    <!-- ADD THIS DEPENDENCY TO YOUR pom.xml -->
    <!-- BEGIN -->
    <dependency>
      <groupId>com.oracle.cryptoj</groupId>
      <artifactId>cryptoj</artifactId>
      <version>1.0.0.0</version>
    </dependency>
    <!-- END -->
  </dependencies>
</project>

Install-file. After you have finished editing the pom.xml file, you are now ready to use the mvn install:install-file command to put the weblogic-maven-plugin.jar file into your Maven repository.

C:\>set JAVA_HOME=C:\Applications\Java\jdk1.6.0_20\x64
C:\>set PATH="%JAVA_HOME%\bin";%PATH%

C:\>set MAVEN_HOME=C:\Applications\NetBeans\NetBeans 8.1\java\maven
C:\>set PATH="%MAVEN_HOME%\bin";%PATH%

C:\>set MW_HOME=C:\Applications\wls1036
C:\>cd %MW_HOME%\wlserver\server\lib

C:\Applications\wls1036\wlserver\server\lib>mvn install:install-file -DpomFile=.\META-INF\maven\com.oracle.weblogic\weblogic-maven-plugin\pom.xml -Dfile=weblogic-maven-plugin.jar

Check your .m2\repositories directory afterwords to verify it was installed successfully. Now that the crypto library, the WebLogic config/key files, and the plugin are in the Maven repository, it’s time to update your project’s pom.xml to automatically deploy to WebLogic.

Project POM

After installing the crypto library into your Maven repository, generating the WebLogic config/key files and installing them into your Maven repository, and generating the weblogic-maven-plugin.jar file and installing it into your Maven repository, you are now finally ready to configure your application for automated deployment to WebLogic. You will need to edit your project’s pom.xml and add the following pieces:

  1. A <profile> for deployment
  2. A <plugin> to extract the WebLogic config/key files
  3. A <plugin> to deploy to WebLogic

So let’s look at this configuration and see how all of these pieces fit together to automatically deploy your artifact to WebLogic.

Add to pom.xml

Here is an example showing what you need to add to your project’s pom.xml file. This example brings together everything you have generated and configured. Let’s take a look at this in more detail.

<profiles>
  <profile> 
    <!-- PROFILE SPECIFICALLY FOR DEPLOYING TO LOCALHOST -->    
    <!-- ADD ADDITIONAL PROFILES FOR DIFFERENT ENVIRONMENTS -->  
    <id>deploy-localhost</id>

    <!-- DEPENDENCY ON THE **LOCALHOST** CONFIG/KEY FILES -->
    <!-- DIFFERENT ENVIRONMENTS WILL HAVE THEIR OWN CONFIG/KEY FILES -->
    <dependencies>
      <dependency>
        <groupId>com.oracle.weblogic.keys</groupId>
        <artifactId>localhost</artifactId>
        <version>1.0.0.0</version>
        <type>zip</type>  
        <scope>provided</scope>
      </dependency>        
    </dependencies>

    <build>
      <plugins>

        <!-- UNPACK CONFIG/KEY FILES TO ./target/keys DIRECTORY -->
        <plugin>  
          <groupId>org.apache.maven.plugins</groupId>  
          <artifactId>maven-dependency-plugin</artifactId>  
          <version>2.6</version>  
          <executions>  
            <execution>  
              <id>unpack-dependencies</id>  
              <phase>prepare-package</phase>  
              <goals>  
                <goal>unpack-dependencies</goal>  
              </goals>  
              <configuration>     
                <includeArtifactIds>localhost</includeArtifactIds>         
                <outputDirectory>
                  ${project.build.directory}/keys
                </outputDirectory>             
              </configuration>  
            </execution>  
          </executions>  
        </plugin>  

        <!-- DEPLOY WAR TO "myserver" ON WEBLOGIC DOMAIN -->
        <plugin> 
          <groupId>com.oracle.weblogic</groupId>
          <artifactId>weblogic-maven-plugin</artifactId>
          <version>10.3.6.0</version> 
          <configuration> 
            <adminurl>t3://localhost:7001</adminurl>
            <targets>myserver</targets>
            <userConfigFile>${project.build.directory}/keys/wls.config</userConfigFile>
            <userKeyFile>${project.build.directory}/keys/wls.key</userKeyFile>            
            <upload>true</upload> 
            <action>deploy</action> 
            <remote>false</remote> 
            <verbose>true</verbose> 
            <source>
              ${project.build.directory}/${project.build.finalName}.${project.packaging}
            </source> 
            <name>${project.build.finalName}</name> 
          </configuration> 
          <executions> 
            <execution> 
              <phase>install</phase> 
              <goals> 
                <goal>deploy</goal> 
              </goals> 
            </execution> 
          </executions> 
        </plugin> 
      </plugins>
    </build>
  </profile>
</profiles>

Create a <profile> for an environment. A <profile> is created with the value <id>deploy-localhost</id>. This <id> value makes it clear this profile is for localhost deployment. Each environment gets its own profile.

Configure <dependency> on the config/key files. This <dependency> is within the <profile> and that’s on purpose! The <dependency> belongs in the <profile> because:

  • The config/key files are only needed for deployment
  • The config/key files are unique to each environment

You can put the <dependency> at the project level, but if you do that it may end up being packaged with your artifact. This doesn’t make any sense to do because this <dependency> is only used for automated deployments.

Configure config/key <plugin>. Here you use maven-dependency-plugin and its unpack-dependencies goal. Remember, the config/key files are in the Maven repository as a ZIP artifact, but you need to get at the individual files inside the ZIP artifact. Using the maven-dependency-plugin and its unpack-dependencies goal will do this for you. The maven-dependency-plugin will unzip the files to <outputDirectory>, which in this example is the target/keys directory.

Now you might ask, “Why not just put the config/key files somewhere on the file system? Why go through the extra effort to get them out of the Maven repository?” The answer is that it’s actually much less effort getting it from the Maven repository, and here’s why. It’s automated! Once the keys are in the Maven repository and your project’s pom.xml file is configured, everything is completely automated after that. No need to have any extra manual steps on any machine that will be running the automated deploys. How cool is that!

Configure deployment <plugin>. You’ve finally gotten to configuring weblogic-maven-plugin itself. Bet you were never going to get here, huh? Anyway, the configuration is fairly trivial. The <adminurl>t3://localhost:7001</adminurl> value is exactly the same used by WLST in the “Key Pair Files” section. The <targets>myserver</targets> value is a comma-separated list of the names of the servers on that WebLogic domain you want to deploy to. The <userConfigFile> and <userKeyFile> point to the config/key files that are automatically pulled out of the Maven repository and unzipped for you by maven-dependency-plugin. The <source> value is the artifact your project built, typically a WAR like .\target\helloworld-1.0.0.0.war. Finally, the <name> value is the name given to the deployment inside of WebLogic. This value is important because if the plugin finds something deployed to WebLogic that has the same name, it will be replaced. This is typically what you want to do, because the whole point of automating deployments is replace what’s out there with the latest and greatest version.

That’s it! If you run your project and see what happens.

```bat C:>set JAVA_HOME=C:\Applications\Java\jdk1.6.0_20\x64 C:>set PATH=“%JAVA_HOME%\bin”;%PATH%

C:>set MAVEN_HOME=C:\Applications\NetBeans\NetBeans 8.1\java\maven C:>set PATH=“%MAVEN_HOME%\bin”;%PATH%

C:>Project C:\Project>mvn clean install -P deploy-localhost ```

If WebLogic is up and running, and everything is configured correctly, you should get SUCCESS. If you do, congratulations!

Target Assignments:
+ helloworld-1.0.0.0-SNAPSHOT  myserver
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------

If you login to the WebLogic admin console and browse to the deployments, you’ll see your application listed. Figure 2 shows an example.

Figure 2 - Deployments screenshot

Deployments screenshot
Deployments screenshot

Summary

It took a while to get here, but you finally made it. Let’s quickly review. The goal is to automate deployments to WebLogic using the weblogic-maven-plugin. To achieve this goal, you must:

  1. Download, install, and configure WebLogic
  2. Create a WebLogic domain, which also automatically creates an admin server for the domain.
  3. Install the WebLogic crypto libraries into your Maven repository
  4. Generate the WebLogic config/key files and install them into your Maven repository
  5. Generate the WebLogic weblogic-maven-plugin.jar file and install it into your Maven repository.
  6. Fix a few WebLogic bugs along the way :)
  7. Add all the configuration to your project’s pom.xml to get the weblogic-maven-plugin working.

It’s all a little exhausting, but once it’s done the benefits of having automated deploys is well worth it.

References

Oracle WebLogic Server Installers. (n.d.). oracle.com. Retrieved from http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-main-097127.html.

Blathers, B. (2011, February 21). Using Secure Config Files with The WebLogic Maven Plugin. Retrieved from http://buttso.blogspot.com/2011/02/using-secure-config-files-with-weblogic.html.

Eisele, M. (2011, January 15). Installing and Using the WebLogic 10.3.4.0 Maven Plug-In for Deployment. Retrieved from http://blog.eisele.net/2011/01/using-and-installing-weblogic-10340.html.

Using the WebLogic Development Maven Plug-in. (n.d.). oracle.com. Retrieved from http://docs.oracle.com/middleware/1212/wls/WLPRG/maven.htm#WLPRG620.

Wednesday, July 20, 2016

Version Number Strategy

Abstract

I am working on a new open source project named Riviera. The purpose of Riviera is to be a database versioning source code management tool. Riviera is a Java based implementation of the philosophy and practice of database version control written about by K. Scott Allen. But before Riviera can manage changing database versions, it first must know how those numbers are going to change. The purpose of this post is to define a clear strategy for understanding how version numbers change throughout the software development life cycle.

Numbers

Versions will consist of 4 integers separated by dots with an optional dash qualifier at the end. The format for a version number is A.B.C.D[-QUALIFIER]. Let’s take a look at what each of these numbers mean.

A

This represents a major version. This number is used by a project manager to track releases. How and when this number changes is up to the project. Most like to change this number when a significant change is made to the project. Others like to change this number on a yearly basis. Determine how you want to change this number and stay consistent. Major versions can’t get to production without planned releases, which is what’s next, B.

B

This represents a planned release of the major version. This value increments every planned release. A.B together are critical for project managers to plan, estimate, and track features in releases.

NOTE Planning releases? What about Scrum? What about development teams determining what to work on each sprint, scrum masters, and no project managers? Well, if you are working in an environment like this, congratulations! Now back to reality :)

Suppose a new project is spinning up. Project managers start planning for release “1.0” - which is the 1st planned release 0 of major version 1. This release will include features f1, f2, & f3.

While developers are working on “1.0”, project managers can start planning for release “1.1” - which is the 2nd planned release 1 of major version 1. This release will include features f4 & f5.

And so planning continues following this pattern. The scope of features for A.B is determined and the development team works on them. This planning works great until a bug is found in production. To get emergency bug fixes, C is needed.

C

This represents an emergency bug fix of a planned release. Recall that a planned release is represented by A.B. An emergency bug fix of A.B is represented by A.B.C. A.B.C together are critical for project managers to plan, estimate, and track bug fixes.

If a bug is found in “1.3”, and must be fixed in production immediately, the 1st bug fix of “1.3” will be “1.3.1”. Once “1.3.1” goes to production, the C version number keeps incrementing as more emergency bug fixes need to be made:

  • “1.3.1” – 1st emergency bug fix of “1.3”
  • “1.3.2” – 2nd emergency bug fix of “1.3”
  • “1.3.3” – 3rd emergency bug fix of “1.3”
  • “1.3.4” – 4th emergency bug fix of “1.3”

Project managers can plan releases all they want, but nothing will get done unless the software gets built. D makes sure builds can happen. Let’s take a look at D next.

D

This represents an incremental build number. This number is typically manged by some automated build system (Maven) and is used for internal purposes only.

The build number tracks the number of builds made of a planned release or an emergency bug fix. Let’s take a look at each of these.

Incremental build of a planned release.

Suppose the development team is working on planned release “1.3”. As features are finished, builds are made for testing. Each build increments the D value.

  • 1.3.0.0 – 1st build of planned release “1.3”
  • 1.3.0.1
  • 1.3.0.2
  • 1.3.0.3
  • 1.3.0.4

Ultimately, when “1.3” is finished and ready to go to production, the internally tracked build going to production may be 1.3.0.15.

Incremental build of emergency bug fix.

Suppose the development team is working on emergency bug fix “1.3.1”. As the bugs are fixed, builds are made for testing. Each build increments the D value.

  • 1.3.1.0 – 1st build of emergency bug fix “1.3.1”
  • 1.3.1.1
  • 1.3.1.2
  • 1.3.1.3

Ultimately, when the “1.3.1” is finished and ready to go to production, the internally tracked build going to production may be 1.3.1.4.

[-QUALIFIER]

This is an optional part of a version number. Maven uses -SNAPSHOT to represent non-official builds.

GIT, Subversion, CVS, etc.

Now that the format of the version number has been defined, let’s consider the effects on the change control system (GIT, Subversion, CVS, etc.). To do this, we’ll follow a hypothetical development time line. As you read through the time line, reference figure 1 to see how the trunk, branches, and tags change over time.

Time Line

  • Planning for the “1.0” release is complete. Development starts. Trunk is at 1.0.0.0 (a).
  • “1.0” features completed. A build is made for testing. Tag 1.0.0.0 is created from trunk. Trunk becomes 1.0.0.1 (b)
  • “1.0” features completed. A build is made for testing. Tag 1.0.0.1 is created from trunk. Trunk becomes 1.0.0.2 (c)
  • “1.0” features completed. A build is made for testing. Tag 1.0.0.2 is created from trunk. Trunk becomes 1.0.0.3 (d)
  • Planning for “1.1” release is complete. Branch 1.0.0 is created for ongoing “1.0” development. Trunk becomes 1.1.0.0 and “1.1” development starts on trunk. (e)
  • “1.0” features completed. A build is made for testing. Tag 1.0.0.3 is created from branch. Branch becomes 1.0.0.4. Changes from branch merged into trunk. (f)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.0 is created from trunk. Trunk becomes 1.1.0.1 (g)
  • “1.0” features completed. A build is made for testing. Tag 1.0.0.4 is created from branch. Branch becomes 1.0.0.5. Changes from branch merged into trunk. (h)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.1 is created from trunk. Trunk becomes 1.1.0.2 (i)
  • “1.0” FINISHED. Build 1.0.0.4 goes to production (j)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.2 is created from trunk. Trunk becomes 1.1.0.3 (k)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.3 is created from trunk. Trunk becomes 1.1.0.4 (l)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.4 is created from trunk. Trunk becomes 1.1.0.5 (m)
  • “1.0” EMERGENCY BUG FIX. Create branch from 1.0.0.4 tag (the build in production). Branch becomes 1.0.1.0 (n)
  • “1.0.1” EMERGENCY BUG FIX complete. A build is made for testing. Tag 1.0.1.0 is created from branch. Branch becomes 1.0.1.1. Changes in branch merged into trunk (o)
  • “1.0.1” EMERGENCY BUG FIX complete. A build is made for testing. Tag 1.0.1.1 is created from branch. Branch becomes 1.0.1.2. Changes in branch merged into trunk (p)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.5 is created from trunk. Trunk becomes 1.1.0.6 (q)
  • “1.0.1” EMERGENCY BUG FIX complete. A build is made for testing. Tag 1.0.1.2 is created from branch. Branch becomes 1.0.1.3. Changes in branch merged into trunk (r)
  • “1.0.1” FINISHED. Build 1.0.1.2 goes to production (s)
  • And it continues…

Figure 1 - Trunk, Branches, & Tags

 TRUNK
1.0.0.0------                                       (a)
   |         \
   |         TAG
   |       1.0.0.0                                  (b)
   |
1.0.0.1------                                       (b)
   |         \
   |         TAG
   |       1.0.0.1                                  (c)
   |
1.0.0.2------                                       (c)
   |         \
   |         TAG
   |       1.0.0.2                                  (d)
   |
1.0.0.3------                                       (d)
   |         \
   |       BRANCH
   |       1.0.0.3------                            (e)
   |          |         \
   |          |         TAG
   |          |       1.0.0.3                       (f)
   |          |
   |       1.0.0.4------                            (f)
   |          |         \
   |          |         TAG------
   |          |       1.0.0.4    \                  (h) (j)
   |          |                 BRANCH------
   |       1.0.0.5              1.0.1.0     \       (h) (n)
   |          |                    |        TAG
   |          -                    |      1.0.1.0   (o)
   |                               |
   |                            1.0.1.1------       (o)
   |                               |         \
   |                               |        TAG
   |                               |      1.0.1.1   (p)
   |                               |
   |                            1.0.1.2------       (p)
   |                               |         \
   |                               |        TAG
   |                               |      1.0.1.2   (r) (s)
   |                               |
   |                            1.0.1.3             (r)
   |
1.1.0.0------                                       (e)
   |         \
   |         TAG
   |       1.1.0.0                                  (g)
   |
1.1.0.1------                                       (g)
   |         \
   |         TAG
   |       1.1.0.1                                  (i)
   |
1.1.0.2------                                       (i)     
   |         \
   |         TAG
   |       1.1.0.2                                  (k)
   |
1.1.0.3------                                       (k)     
   |         \
   |         TAG
   |       1.1.0.3                                  (l)
   |
1.1.0.4------                                       (l)     
   |         \
   |         TAG
   |       1.1.0.4                                  (m)
   |
1.1.0.5------                                       (m)     
   |         \
   |         TAG
   |       1.1.0.5                                  (q)
   |
1.1.0.6                                             (q)

Summary

Handling version numbers is always a tricky thing, especially when you have multiple lines of development going on different branches and all the work needs to be coordinated and merged. This strategy seems to work well. The hard part is sticking to it!

References

Allen, S. (2008, February 4). Versioning Databases - Branching and Merging. Ode to Code. Retrieved from http://odetocode.com/blogs/all?page=75.

Tuesday, July 19, 2016

Welcome to Scrivener

Abstract

Begin typing your abstract paragraph here. This paragraph should not be indented. It should range between 150 and 250 words. This should be accurate, nonevaluative, readable, and concise. The reader should know exactly what this blog post is about.

Scrivener

Scrivener is a powerful writing tool which can be used for all kinds of writing. Originally developed for writing novels, Scrivener is now used for short stories, plays, scripts, theses, and lots of other kinds of writing including blogging.

Scrivener separates the content of what you write from its output format. Compiling is how to get the output format. For bloggers, Scrivener supports the markdown syntax. Let’s take a look at markdown.

Markdown

Markdown is a markup format for writers that’s easier than HTML, but is ultimately turned into HTML. A cheat sheet shows just how simple it is. Scrivener compiles a markdown formatted writing into HTML. After that, copy & paste the HTML into the HTML Editor of your blogging platform.

NOTE The HTML generated is quite simple. Your blog’s CSS will need to be updated to present it nicely. Typically somewhere in the settings you’ll find a spot to edit the contents of the blog template. It’s here you can add custom CSS to format the markdown-generated HTML.

Code

All technical blogs will need to show code. There will be int inlineCode = 1; examples. And there will be block code examples referred to by listings. Listing 1 is a Java block code example.

Listing 1 - Java Hello World

public static final void main(String [] args) {
  System.out.println("Hello world!");
}

Images

Images are also essential. Figure 1 is an example of an image. This image is not embedded in the blog. It is referencing an image from another website. This is a bit dangerous to do because if the website removes the image, it will no longer appear on the blog. An alternative is to upload images to the blog and reference the URLs created for those images. Or host the images on a site like Flickr. Or save the images to Dropbox and get a shared link to the image.

Figure 1 - Duke

Java Duke waving
Java Duke waving

Summary

It is always good to wrap up a blog posting with a summary of the contents. Sometimes blog posts are small quick tips and a summary is not necessary. But if the blog post is presenting lengthy contents, then a summary is good to help remind blog readers what they just read.

References

And don’t forget your references! People contribute a lot of information online, so it’s good to cite your sources.

Pritchard, A. (2016, February 26). Markdown Cheatsheet. Website Title. Retrieved from https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet