MA

EN

13 years ago...

ant

a flexible build tool

maven

accumulator of knowledge

ant

maven

2 years ago...

Sam as king saying go to Maven

and the decision was made

but why?

convention over configuration

Project

Structure

src/main/java

src/main/resources

your-java-application

src/test/java

src/test/resources

pom

target

import sys
import os.path
import platform
import os

#These are Joe's files
import findDependency
import srcPath
import jarFiles
import buildOrder
import approvedJars
import projectTypes
import antParse
import findUtil
import libraryDirectory

import buildUtilityFunctions

# These are only for command line parameters
# not environment variables
projectNamesFound= False
earFileNameSet = False
workingLocSet = False
buildDirSet = False
scriptsHomeSet = False
includesJUnitProprtySet = False

classpathSequence = ''

#Assign identifiers 
for arg in sys.argv:
    keys = arg.split('=')
    if keys[0] == 'workingLoc':
        workingLoc = keys[1]
        workingLocSet = True
        continue
    elif keys[0] == 'buildDir':
        buildDir = keys[1]
        buildDirSet = True
        continue
    elif keys[0] == 'projectNames':
        projectNames = keys[1].split(',')
        projectNamesFound = True
        continue
    elif keys[0] == 'scriptsHome':
        CSX_SCRIPTS_HOME = keys[1]
        scriptsHomeSet = True
        continue
    elif keys[0] == 'earFileName':
        earFileName = keys[1]
        earFileNameSet = True
        continue
    elif keys[0] == 'classpathSequence':
        classpathSequence = keys[1]
        continue
    elif keys[0] == 'includesJUnitClasses':
        includesJUnitProprtySet = True
        includesJUnitClasses = keys[1]

# Verify that the workingLoc command argument is a path that exists
os.chdir(workingLoc)

# build.py script requires a "projectNames" command argument
# The value of projectNames can be an empty string or a specific project name
# Determine the appropriate projects to build according to this input
if projectNamesFound == False:
    print "projectNames is required"
    print "Please enter projectNames="
    sys.exit(1)
elif projectNamesFound == True and projectNames == ['']:
    projectNames = os.listdir(workingLoc)   
    print "projectNames was passed in as blank, make it based on directories: " + str(projectNames)
elif projectNamesFound == True and projectNames == ['PROJECT_TO_BUILD']:
    projectNames = os.listdir(workingLoc)   
    print "projectNames was passed in as PROJECT_TO_BUILD, make it based on directories: " + str(projectNames)
else:
    projectNames = projectTypes.findAllProjectNames(workingLoc, projectNames)

#------------------------------------------------------
# Handle classpath sequencing - Custom or default
#-------------------------------------------------------

# Determine if the run requires a custom classpath build sequence
# Key Terms:
#    EXT = shared.lib.classpath + ext.classpath
#    COMMON = common.classpath
#    MODULE = module.compile.classpath
#    EAR = ear.lib.classpath

#libsDict = buildUtilityFunctions.buildRefIds()
customSeqSet = True
if classpathSequence == '':
    customSeqSet = False
    print ("No custom classpath build sequence entered. Using the default.")
    classpathSequence = "WEBSPHERE, COMMON, MODULE, EAR"

buildUtilityFunctions.customCPSeq = classpathSequence

# cpCount = 0
# cpOrder = ''
# print (classpathSequence.replace(' ', '').split(','))
# for path in classpathSequence.replace(' ', '').split(','):
#     cpOrder += libsDict[path]
#     cpOrder += ' '
#     cpCount += 1
# 
# if cpCount != 4:
#     print ("Invalid amount of entries for the custom classpath sequence.")
#     print ("Enter each of the following keys once to define the custom classpath sequence")
#     print ("\t KEY     | VALUE")
#     print ("---------------------------------------------------")
#     print ("\t WEBSPHERE     | shared.lib.classpath + ext.classpath")
# #         print ("\t SHARED  | shared.lib.classpath")
#     print ("\t COMMON  | common.classpath")
#     print ("\t MODULE  | module.compile.classpath")
#     print ("\t EAR     | ear.lib.classpath")
#     sys.exit(1)

cpOrder = buildUtilityFunctions.parseClasspathSeq(classpathSequence)
    
cpOrder = cpOrder.strip(' ')
cpOrder = '' + cpOrder + ''

if (customSeqSet == True):
    print ("Custom classpath build sequence " + cpOrder + " has been entered.")
else :
    print ("Default classpath build sequence " + cpOrder + " has been assigned.")

#------------------------------------------------------


# Check for the required environment variables
if earFileNameSet == False:
    print "Output EAR file name not entered"
    print "Please enter EAR file name as earFileName="
    sys.exit(1)

if workingLocSet == False:
    print "workingLoc is required"
    print "Please enter workingLoc as workingLoc="
    sys.exit(1)
    
if buildDirSet == False:
    print "buildDir is required"
    print "Please enter buildDir as buildDir="
    sys.exit(1)

if scriptsHomeSet == False:
    print "scriptsHome is required"
    print "Please enter scriptsHome as scriptsHome="
    sys.exit(1) 

if includesJUnitProprtySet == False:
    includesJUnitClasses = True

# Assign the types (ear, war, ejb, util) for each project
projectType = projectTypes.getProjectTypes(workingLoc, projectNames)

# Determine the library directory
libDir = libraryDirectory.determineLibraryDirectory(projectType['ear'][0], workingLoc)
print ('Library directory for the EAR file: ' + libDir)

# Determine the websphere and JSF version of the project
websphereVersion = srcPath.findWebsphereVersion(workingLoc, projectNames)
print ("Project Names: " + str(projectNames))
print ("websphereVersion found ======== " + websphereVersion + " ========")

# Use this list in future leapfrog fixpack
# Compare approved jar file list with the jar files used in this project
approvedJarFile = os.path.join(CSX_SCRIPTS_HOME, 'approvedJars.txt')
jarFiles = jarFiles.getJars(workingLoc, projectNames)
print 'Jar Files: ', jarFiles
notApprovedJars = approvedJars.getApprovedjars(approvedJarFile, jarFiles)

# Determine the dependencies among the projects
projectDependency = findDependency.Dependency(workingLoc, projectNames)

# If the project is old (WAS 7) then dynamically remove the circular dependency
# If the project is new (WAS 8) then print that there is a circular dependency and fail the build
if websphereVersion == '7':
    projectDependency = findDependency.removeCircularDependency(projectDependency, projectType)
    
print 'projectDependency: ', projectDependency

buildSequence = buildOrder.getBuildOrder(projectType['ear'][0], projectDependency[projectType['ear'][0]], projectDependency)
buildSequence = buildSequence.split(' ')
buildSequence = buildOrder.createSet(buildSequence)
buildSequence = buildOrder.buildUtilsFirst(buildSequence, projectType)
print ("PROJECT BUILD ORDER = " + str(buildSequence))

# Now that project build order has been determined, we can remove duplicate projects in the dependency dictionary
# to avoid copying duplicate files into the EAR
projectDependency = findDependency.removeDependencyDuplicates(projectDependency, projectType)
print ("OUTPUT EAR FILE STRUCTURE: " + str(projectDependency))

# Determine the source folders within each project
sourcePath = srcPath.source(workingLoc, projectNames)

# Check if the project requires an <EJB>.jar to be copied into <WEB>.war/WEB-INF/lib/
ejbCopyDict = buildUtilityFunctions.copyEJBForREST(workingLoc, projectType["web"], projectType["ejb"])
print ("EJBs THAT NEED TO BE COPIED INTO <WEB PROJECT>.WAR/WEB-INF/lib: " + str(ejbCopyDict))

antParse.parse(CSX_SCRIPTS_HOME, workingLoc, sourcePath, str(includesJUnitClasses), 
               projectType, projectDependency, buildDir, earFileName, websphereVersion, 
               buildSequence, cpOrder, customSeqSet, libDir, ejbCopyDict)
mvn install

three eyed raven

dev

sec

ops

dev tool

  • it's a build tool, builds your Java apps
     
  • compiles and tests your code
     
  • packages your code
mvn package
.java
.class

.jar   .ear  .war

dev power

  • it's a build tool, builds your Java apps
     
  • compiles and tests your code
     
  • packages your code
     
  • manages your dependencies
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <packaging>jar</packaging>
    <scope>test</scope>
</dependency>

dependencies - gav

develop on the shoulders of giants

security power

  • trusted and secure dependencies
<dependency>

non-maven

<dependency>

maven

security power

  • trusted and secure dependencies
     
  • runs unit tests
     
  • generates test reports
     
  • sonar and nexus integration

ops power

  • automates build process
     
  • integrates easily with build server

three eyed raven

dev

sec

ops

better
developer
life

local environment

eclipse

or

cli

settings.xml

toolchains.xml

JDK

JDK

create a new project
with ease

archetypes

=   templates

mvn archetype:generate

shift left
and build locally with pom

p.roject

o.bject
m.odel

maven

 =   build tools

pom

=   blueprint 

 package (ear)

=   castle

gav

package

deps

props

plugins

parent

mods

pom

1. gav coordinates

<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>

2. packaging

<project>
...
    <packaging>jar</packaging>
...
</project>
mvn install
.java
.class

.jar   .ear  .war

3. properties

<project>
...
  <properties>
    <csx.app.code>en</csx.app.code>
    <context.root>csxstarter</context.root>

    <csx.scm.project>en</csx.scm.project>
    <csx.scm.repo>enterprise-parent</csx.scm.repo>

    <jdk.level>1.8</jdk.level>
    <jvm.vendor>ibm</jvm.vendor>     
  </properties>
...
</project>

4. dependencies

<project>
...
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <packaging>jar</packaging>
            <scope>test</scope>
        </dependencies>
    </dependency>
...
</project>

4a. transitive deps

4b. dep management

parent

children

<dependencyManagement>
    <dependencies>
      ...  
      <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>6.0</version>
        <scope>provided</scope>
      </dependency>
      ...
    </dependencies>
</dependencyManagement>
<dependencies>
  ...  
  <dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
  </dependency>
  ...
</dependencies>

5. plugins

<project>
...
    <plugins>
        <!-- Compiler Plugin -->
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
          <configuration>
            <source>${jdk.level}</source>
            <target>${jdk.level}</target>
            <compilerVersion>${jdk.level}</compilerVersion>
          </configuration>
        </plugin>
    </plugins>
...
</project>

5a. plugin mgmt

children

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
</plugin>

6. modules

<project>
...
  <modules>
    <module>csxstarter-ear</module>
    <module>csxstarter-ejb</module>
    <module>csxstarter-ejbclient</module>
    <module>csxstarter-web</module>
  </modules>
...
</project>

7. parent

children inherit    

  • dependencies

  • plugins

  • properties

  enterprise-parent

gav

package

deps

props

plugins

parent

mods

pom

developer tips

build lifecycle

lifecycle

  • phases
    • goals

default lifecycle

clean lifecycle

<phases>
  <phase>validate</phase>
  <phase>initialize</phase>
  <phase>generate-sources</phase>
  <phase>process-sources</phase>
  <phase>generate-resources</phase>
  <phase>process-resources</phase>
  <phase>compile</phase>
  <phase>process-classes</phase>
  <phase>generate-test-sources</phase>
  <phase>process-test-sources</phase>
  <phase>generate-test-resources</phase>
  <phase>process-test-resources</phase>
  <phase>test-compile</phase>
  <phase>process-test-classes</phase>
  <phase>test</phase>
  <phase>prepare-package</phase>
  <phase>package</phase>
  <phase>pre-integration-test</phase>
  <phase>integration-test</phase>
  <phase>post-integration-test</phase>
  <phase>verify</phase>
  <phase>install</phase>
  <phase>deploy</phase>
</phases>

Maven Goals

mvn install

Maven Goals

mvn clean

Maven Goals

mvn dependency:purge-local-repo

Maven Goals

mvn versions:set -DnewVersion=2.0.0-SNAPSHOT

moving to maven?

automation
file migration
dependenies

MA

EN

DevSecOps

pom

pom

Code Bytes #2 : Maven

By jjcdelrosario

Code Bytes #2 : Maven

  • 19