├── .travis.yml
├── screenshots
├── trigger.png
└── configure.png
├── src
└── main
│ ├── java
│ └── com
│ │ └── orctom
│ │ └── mojo
│ │ └── was
│ │ ├── Constants.java
│ │ ├── utils
│ │ ├── AntXmlPlexusConfigurationWriter.java
│ │ └── AntTaskUtils.java
│ │ ├── WebSphereServiceImpl.java
│ │ ├── WASDeployMojo.java
│ │ └── AbstractWASMojo.java
│ └── resources
│ └── org
│ └── apache
│ └── maven
│ └── ant
│ └── tasks
│ └── antlib.xml
├── .gitignore
├── pom.xml
├── LICENSE
└── README.md
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 |
3 | notifications:
4 | email: false
5 |
--------------------------------------------------------------------------------
/screenshots/trigger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orctom/was-maven-plugin/HEAD/screenshots/trigger.png
--------------------------------------------------------------------------------
/screenshots/configure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orctom/was-maven-plugin/HEAD/screenshots/configure.png
--------------------------------------------------------------------------------
/src/main/java/com/orctom/mojo/was/Constants.java:
--------------------------------------------------------------------------------
1 | package com.orctom.mojo.was;
2 |
3 | /**
4 | * Constants that been used in this plugin
5 | * Created by CH on 3/19/14.
6 | */
7 | public class Constants {
8 |
9 | public static final String PLUGIN_ID = "was-maven-plugin";
10 | public static final String KEY_DEPLOY_TARGETS = "deploy_targets";
11 | }
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Package Files #
4 | *.war
5 | *.ear
6 | /was-maven-plugin.iml
7 | /target
8 | /.idea
9 | /ssl
10 | /scripts
11 | /src/it/multi-targets/target
12 | /pom.xml.tag
13 | /pom.xml.next
14 | /release.properties
15 | /pom.xml.releaseBackup
16 |
17 | .project
18 | .classpath
19 | *versionsBackup
20 | */*versionsBackup
21 |
22 | */.settings/
23 | */.idea/
24 | */.gradle/
25 | */.svn/
26 | */target/
27 | */build/
28 | */bin/
29 | */classes/
30 |
31 | .settings/
32 | .idea/
33 | .gradle/
34 | .svn/
35 | target/
36 | build/
37 | bin/
38 | classes/
--------------------------------------------------------------------------------
/src/main/resources/org/apache/maven/ant/tasks/antlib.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/main/java/com/orctom/mojo/was/utils/AntXmlPlexusConfigurationWriter.java:
--------------------------------------------------------------------------------
1 | package com.orctom.mojo.was.utils;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one
5 | * or more contributor license agreements. See the NOTICE file
6 | * distributed with this work for additional information
7 | * regarding copyright ownership. The ASF licenses this file
8 | * to you under the Apache License, Version 2.0 (the
9 | * "License"); you may not use this file except in compliance
10 | * with the License. You may obtain a copy of the License at
11 | *
12 | * http://www.apache.org/licenses/LICENSE-2.0
13 | *
14 | * Unless required by applicable law or agreed to in writing,
15 | * software distributed under the License is distributed on an
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 | * KIND, either express or implied. See the License for the
18 | * specific language governing permissions and limitations
19 | * under the License.
20 | */
21 |
22 | import org.codehaus.plexus.configuration.PlexusConfiguration;
23 | import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
24 | import org.codehaus.plexus.util.xml.XMLWriter;
25 |
26 | import java.io.IOException;
27 | import java.io.Writer;
28 |
29 | /**
30 | * Write a plexus configuration to a stream Note: This class was originally
31 | * copied from plexus-container-default. It is duplicated here to maintain
32 | * compatibility with both Maven 2.x and Maven 3.x.
33 | */
34 | public class AntXmlPlexusConfigurationWriter {
35 |
36 | public void write(PlexusConfiguration configuration, Writer writer) throws IOException {
37 | int depth = 0;
38 |
39 | PrettyPrintXMLWriter xmlWriter = new PrettyPrintXMLWriter(writer);
40 | write(configuration, xmlWriter, depth);
41 | }
42 |
43 | private void write(PlexusConfiguration c, XMLWriter w, int depth) throws IOException {
44 | int count = c.getChildCount();
45 |
46 | if (count == 0) {
47 | writeTag(c, w, depth);
48 | } else {
49 | w.startElement(c.getName());
50 | writeAttributes(c, w);
51 |
52 | for (int i = 0; i < count; i++) {
53 | PlexusConfiguration child = c.getChild(i);
54 |
55 | write(child, w, depth + 1);
56 | }
57 |
58 | w.endElement();
59 | }
60 | }
61 |
62 | private void writeTag(PlexusConfiguration c, XMLWriter w, int depth) throws IOException {
63 | w.startElement(c.getName());
64 |
65 | writeAttributes(c, w);
66 |
67 | String value = c.getValue(null);
68 | if (value != null) {
69 | w.writeText(value);
70 | }
71 |
72 | w.endElement();
73 | }
74 |
75 | private void writeAttributes(PlexusConfiguration c, XMLWriter w) throws IOException {
76 | String[] names = c.getAttributeNames();
77 |
78 | for (int i = 0; i < names.length; i++) {
79 | w.addAttribute(names[i], c.getAttribute(names[i], null));
80 | }
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/src/main/java/com/orctom/mojo/was/WebSphereServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.orctom.mojo.was;
2 |
3 | import com.orctom.was.model.Command;
4 | import com.orctom.was.model.WebSphereModel;
5 | import com.orctom.was.model.WebSphereServiceException;
6 | import com.orctom.was.service.impl.AbstractWebSphereServiceImpl;
7 | import org.codehaus.plexus.util.FileUtils;
8 | import org.codehaus.plexus.util.StringUtils;
9 | import org.codehaus.plexus.util.cli.*;
10 |
11 | import java.io.File;
12 |
13 | /**
14 | * Service to execute WAS tasks
15 | * Created by hao on 11/11/15.
16 | */
17 | public class WebSphereServiceImpl extends AbstractWebSphereServiceImpl {
18 |
19 | public WebSphereServiceImpl(WebSphereModel model, String targetDir) {
20 | super(model, targetDir);
21 | }
22 |
23 | @Override
24 | protected void executeCommand(Command command) {
25 | try {
26 | Commandline commandLine = new Commandline();
27 | commandLine.setExecutable(command.getExecutable());
28 | commandLine.setWorkingDirectory(command.getWorkingDir());
29 | for (String arg : command.getArgEntriesAsList()) {
30 | commandLine.createArg().setLine(arg);
31 | }
32 |
33 | StringStreamConsumer outConsumer = new StringStreamConsumer();
34 | StringStreamConsumer errConsumer = new StringStreamConsumer();
35 | executeCommand(commandLine, outConsumer, errConsumer, model.isVerbose());
36 |
37 | String out = outConsumer.getOutput();
38 | FileUtils.fileWrite(new File(command.getBuildScriptPath() + ".log"), out);
39 |
40 | if (model.isFailOnError() && (
41 | out.contains("com.ibm.ws.scripting.ScriptingException") || out.contains("com.ibm.bsf.BSFException"))) {
42 | throw new WebSphereServiceException("Failed to execute the task, Please see the log for more details");
43 | }
44 |
45 | String error = errConsumer.getOutput();
46 | if (StringUtils.isNotEmpty(error)) {
47 | System.err.println(error);
48 | }
49 | } catch (CommandLineTimeOutException e) {
50 | throw new WebSphereServiceException("Failed to execute the task." +
51 | "Please ensure remote WAS or Deployment Manager is running. " + e.getMessage(), e);
52 | } catch (Exception e) {
53 | throw new WebSphereServiceException(e.getMessage(), e);
54 | }
55 | }
56 |
57 | public static void executeCommand(Commandline commandline, StreamConsumer outConsumer, StreamConsumer errorConsumer, boolean isVerbose)
58 | throws CommandLineException {
59 | if (isVerbose) {
60 | System.out.println("Executing command:\n" + StringUtils.join(commandline.getShellCommandline(), " "));
61 | }
62 |
63 | int returnCode = CommandLineUtils.executeCommandLine(commandline, outConsumer, errorConsumer, 1800);
64 |
65 | if (returnCode != 0) {
66 | String msg = "Failed to deploy, return code: " + returnCode + ". Please make sure target WAS is alive and reachable.";
67 | throw new WebSphereServiceException(msg);
68 | } else {
69 | System.out.println("Return code: " + returnCode);
70 | }
71 | }
72 |
73 | class StringStreamConsumer implements StreamConsumer {
74 | private String ls = System.getProperty("line.separator");
75 | private StringBuffer string = new StringBuffer();
76 |
77 | public void consumeLine(String line) {
78 | string.append(line).append(ls);
79 | System.out.println(line);
80 | }
81 |
82 | public String getOutput() {
83 | return string.toString();
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/orctom/mojo/was/WASDeployMojo.java:
--------------------------------------------------------------------------------
1 | package com.orctom.mojo.was;
2 |
3 | import com.google.common.base.Throwables;
4 | import com.orctom.mojo.was.utils.AntTaskUtils;
5 | import com.orctom.was.model.WebSphereModel;
6 | import com.orctom.was.model.WebSphereServiceException;
7 | import org.apache.maven.plugin.MojoExecutionException;
8 | import org.apache.maven.plugin.MojoFailureException;
9 | import org.apache.maven.plugins.annotations.LifecyclePhase;
10 | import org.apache.maven.plugins.annotations.Mojo;
11 | import org.apache.maven.plugins.annotations.Parameter;
12 | import org.codehaus.plexus.configuration.PlexusConfiguration;
13 | import org.codehaus.plexus.util.StringUtils;
14 |
15 | import java.io.File;
16 | import java.io.IOException;
17 | import java.util.Set;
18 | import java.util.concurrent.ExecutorService;
19 | import java.util.concurrent.Executors;
20 | import java.util.concurrent.TimeUnit;
21 |
22 | /**
23 | * websphere deployment mojo
24 | * Created by CH on 3/4/14.
25 | */
26 | @Mojo(name = "deploy", defaultPhase = LifecyclePhase.PRE_INTEGRATION_TEST, requiresDirectInvocation = true, threadSafe = true)
27 | public class WASDeployMojo extends AbstractWASMojo {
28 |
29 | @Parameter
30 | protected String parallel;
31 |
32 | @Override
33 | public void execute() throws MojoExecutionException, MojoFailureException {
34 | getLog().info(Constants.PLUGIN_ID + " - deploy");
35 | Set models = getWebSphereModels();
36 |
37 | if (null == models || models.isEmpty()) {
38 | getLog().info("[SKIPPED DEPLOYMENT] empty target server configured, please check your configuration");
39 | return;
40 | }
41 |
42 | final String workingDir = project.getBuild().getDirectory() + File.separator + Constants.PLUGIN_ID + File.separator + "py" + File.separator;
43 |
44 | boolean parallelDeploy = StringUtils.isEmpty(parallel) ? models.size() > 1 : Boolean.valueOf(parallel);
45 |
46 | if (parallelDeploy) {
47 | int numOfProcessors = Runtime.getRuntime().availableProcessors();
48 | int poolSize = models.size() > numOfProcessors ? numOfProcessors : models.size();
49 | ExecutorService executor = Executors.newFixedThreadPool(poolSize);
50 | for (final WebSphereModel model : models) {
51 | executor.execute(new Runnable() {
52 | @Override
53 | public void run() {
54 | execute(model, workingDir);
55 | }
56 | });
57 | }
58 | executor.shutdown();
59 |
60 | try {
61 | executor.awaitTermination(20, TimeUnit.MINUTES);
62 | } catch (InterruptedException e) {
63 | e.printStackTrace();
64 | }
65 | } else {
66 | for (WebSphereModel model : models) {
67 | execute(model, workingDir);
68 | }
69 | }
70 | }
71 |
72 | private void execute(WebSphereModel model, String workingDir) {
73 | getLog().info("============================================================");
74 | getLog().info("[DEPLOY] " + model.getHost() + " " + model.getApplicationName());
75 | getLog().info("============================================================");
76 |
77 | try {
78 | getLog().info("==================== pre-steps =======================");
79 | executeAntTasks(model, super.preSteps);
80 | getLog().info("====================== deploy ========================");
81 | new WebSphereServiceImpl(model, workingDir).deploy();
82 | getLog().info("==================== post-steps ======================");
83 | executeAntTasks(model, super.postSteps);
84 | } catch (Throwable t) {
85 | if (failOnError) {
86 | throw new WebSphereServiceException(t);
87 | } else {
88 | getLog().error("############## Exception occurred during deploying to WebSphere ###############");
89 | getLog().error(Throwables.getStackTraceAsString(t));
90 | }
91 | }
92 | }
93 |
94 | private void executeAntTasks(WebSphereModel model, PlexusConfiguration[] targets) throws IOException, MojoExecutionException {
95 | if (null == targets || 0 == targets.length) {
96 | getLog().info("Skipped, not configured.");
97 | return;
98 | }
99 | for (PlexusConfiguration target : targets) {
100 | AntTaskUtils.execute(model, target, project, projectHelper, pluginArtifacts, getLog());
101 | }
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 | com.orctom.mojo
4 | was-maven-plugin
5 | maven-plugin
6 | 1.1.3.4-SNAPSHOT
7 |
8 | was-maven-plugin
9 | Maven plugin to deploy war/ear to WebSphere
10 | https://github.com/orctom/was-maven-plugin/
11 |
12 |
13 | https://github.com/orctom/was-maven-plugin/issues
14 | GitHub
15 |
16 |
17 |
18 |
19 | Apache License, Version 2.0
20 | http://www.apache.org/licenses/LICENSE-2.0
21 | repo
22 |
23 |
24 |
25 |
26 | https://github.com/orctom/was-maven-plugin/
27 | scm:git:git@github.com:orctom/was-maven-plugin.git
28 | scm:git:git@github.com:orctom/was-maven-plugin.git
29 | HEAD
30 |
31 |
32 |
33 |
34 | Hao Chen
35 | orctom@gmail.com
36 |
37 |
38 |
39 |
40 | UTF-8
41 | 3.0.4
42 |
43 |
44 |
45 |
46 |
47 |
48 | org.apache.maven.plugins
49 | maven-compiler-plugin
50 | 3.1
51 |
52 | 1.6
53 | 1.6
54 |
55 |
56 |
57 | org.apache.maven.plugins
58 | maven-plugin-plugin
59 | 3.2
60 |
61 | was
62 | true
63 |
64 |
65 |
66 | mojo-descriptor
67 | process-classes
68 |
69 | descriptor
70 |
71 |
72 |
73 |
74 |
75 | org.apache.maven.plugins
76 | maven-surefire-plugin
77 | 2.17
78 |
79 | true
80 |
81 |
82 |
83 | org.codehaus.mojo
84 | versions-maven-plugin
85 | 2.1
86 |
87 |
88 | org.apache.maven.plugins
89 | maven-scm-plugin
90 | 1.9
91 |
92 |
93 | org.apache.maven.plugins
94 | maven-release-plugin
95 | 2.5
96 |
97 | forked-path
98 | false
99 | -Prelease ${release.args}
100 | @{project.version}
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | release
109 |
110 |
111 |
112 | org.apache.maven.plugins
113 | maven-source-plugin
114 | 2.2.1
115 |
116 |
117 | attach-sources
118 | verify
119 |
120 | jar
121 |
122 |
123 |
124 |
125 |
126 | org.apache.maven.plugins
127 | maven-javadoc-plugin
128 | 2.9.1
129 |
130 |
131 | attach-javadocs
132 | verify
133 |
134 | jar
135 |
136 |
137 |
138 |
139 |
140 | org.apache.maven.plugins
141 | maven-jar-plugin
142 | 2.4
143 |
144 |
145 |
146 | test-jar
147 |
148 |
149 |
150 |
151 |
152 | org.apache.maven.plugins
153 | maven-gpg-plugin
154 | 1.1
155 |
156 |
157 | sign-artifacts
158 | verify
159 |
160 | sign
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 | org.apache.maven
173 | maven-plugin-api
174 | 3.2.1
175 |
176 |
177 | org.apache.maven
178 | maven-core
179 | ${maven.version}
180 |
181 |
182 | org.apache.maven
183 | maven-model
184 | ${maven.version}
185 |
186 |
187 | org.apache.maven
188 | maven-settings
189 | ${maven.version}
190 |
191 |
192 | org.apache.maven.plugin-tools
193 | maven-plugin-annotations
194 | 3.2
195 |
196 |
197 | org.codehaus.plexus
198 | plexus-utils
199 | 3.0.10
200 |
201 |
202 | org.apache.maven.shared
203 | file-management
204 | 1.2.1
205 |
206 |
207 | org.mockito
208 | mockito-core
209 | 1.9.5
210 | test
211 |
212 |
213 | org.apache.maven.shared
214 | maven-plugin-testing-harness
215 | 1.1
216 | test
217 |
218 |
219 | org.apache.ant
220 | ant
221 | 1.8.3
222 |
223 |
224 | com.orctom.was
225 | was-util
226 | 1.1.3.2
227 |
228 |
229 | junit
230 | junit
231 | 4.8.2
232 | test
233 |
234 |
235 |
236 |
--------------------------------------------------------------------------------
/src/main/java/com/orctom/mojo/was/utils/AntTaskUtils.java:
--------------------------------------------------------------------------------
1 | package com.orctom.mojo.was.utils;
2 |
3 | import com.orctom.mojo.was.Constants;
4 | import com.orctom.was.model.WebSphereModel;
5 | import com.orctom.was.utils.CommandUtils;
6 | import org.apache.maven.artifact.Artifact;
7 | import org.apache.maven.artifact.DependencyResolutionRequiredException;
8 | import org.apache.maven.plugin.MojoExecutionException;
9 | import org.apache.maven.plugin.logging.Log;
10 | import org.apache.maven.project.MavenProject;
11 | import org.apache.maven.project.MavenProjectHelper;
12 | import org.apache.tools.ant.BuildException;
13 | import org.apache.tools.ant.DefaultLogger;
14 | import org.apache.tools.ant.Project;
15 | import org.apache.tools.ant.ProjectHelper;
16 | import org.apache.tools.ant.taskdefs.Typedef;
17 | import org.apache.tools.ant.types.Path;
18 | import org.codehaus.plexus.configuration.PlexusConfiguration;
19 | import org.codehaus.plexus.util.FileUtils;
20 | import org.codehaus.plexus.util.StringUtils;
21 |
22 | import java.io.*;
23 | import java.util.ArrayList;
24 | import java.util.Collection;
25 | import java.util.List;
26 | import java.util.Properties;
27 |
28 | /**
29 | * Utils to execute ant tasks
30 | * Created by CH on 3/19/14.
31 | */
32 | public class AntTaskUtils {
33 |
34 | /**
35 | * The refid used to store the Maven project object in the Ant build.
36 | */
37 | private final static String DEFAULT_MAVEN_PROJECT_REFID = "maven.project";
38 |
39 | /**
40 | * The refid used to store the Maven project object in the Ant build.
41 | */
42 | private final static String DEFAULT_MAVEN_PROJECT_HELPER_REFID = "maven.project.helper";
43 |
44 | /**
45 | * The path to The XML file containing the definition of the Maven tasks.
46 | */
47 | private final static String ANTLIB = "org/apache/maven/ant/tasks/antlib.xml";
48 |
49 | /**
50 | * The default target name.
51 | */
52 | private final static String DEFAULT_ANT_TARGET_NAME = "main";
53 |
54 | public static void execute(WebSphereModel model, PlexusConfiguration target, MavenProject project,
55 | MavenProjectHelper projectHelper, List pluginArtifact, Log logger)
56 | throws IOException, MojoExecutionException {
57 | // The fileName should probably use the plugin executionId instead of the targetName
58 | boolean useDefaultTargetName = false;
59 | String antTargetName = target.getAttribute("name");
60 | if (null == antTargetName) {
61 | antTargetName = DEFAULT_ANT_TARGET_NAME;
62 | useDefaultTargetName = true;
63 | }
64 | StringBuilder fileName = new StringBuilder(50);
65 | fileName.append("build");
66 | if (StringUtils.isNotBlank(model.getHost())) {
67 | fileName.append("-").append(model.getHost());
68 | }
69 | if (StringUtils.isNotBlank(model.getApplicationName())) {
70 | fileName.append("-").append(model.getApplicationName());
71 | }
72 | fileName.append("-").append(antTargetName).append("-").append(CommandUtils.getTimestampString()).append(".xml");
73 | File buildFile = getBuildFile(project, fileName.toString());
74 |
75 | if (model.isVerbose()) {
76 | logger.info("ant fileName: " + fileName);
77 | }
78 |
79 | if (buildFile.exists()) {
80 | logger.info("[SKIPPED] already executed");
81 | return;
82 | }
83 |
84 | StringWriter writer = new StringWriter();
85 | AntXmlPlexusConfigurationWriter xmlWriter = new AntXmlPlexusConfigurationWriter();
86 | xmlWriter.write(target, writer);
87 |
88 | StringBuffer antXML = writer.getBuffer();
89 |
90 | if (useDefaultTargetName) {
91 | stringReplace(antXML, "\n";
95 | antXML.insert(0, xmlHeader);
96 | final String projectOpen = "\n";
97 | int index = antXML.indexOf(" pluginArtifact, Log logger)
117 | throws MojoExecutionException {
118 | try {
119 | Project antProject = new Project();
120 | ProjectHelper.configureProject(antProject, antBuildFile);
121 | antProject.init();
122 |
123 | setupLogger(antBuildFile, logger, antProject);
124 |
125 | antProject.setBaseDir(project.getBasedir());
126 |
127 | Path p = new Path(antProject);
128 | p.setPath(StringUtils.join(project.getCompileClasspathElements().iterator(), File.pathSeparator));
129 |
130 | antProject.addReference("maven.compile.classpath", p);
131 |
132 | p = new Path(antProject);
133 | p.setPath(StringUtils.join(project.getRuntimeClasspathElements().iterator(), File.pathSeparator));
134 | antProject.addReference("maven.runtime.classpath", p);
135 |
136 | p = new Path(antProject);
137 | p.setPath(StringUtils.join(project.getTestClasspathElements().iterator(), File.pathSeparator));
138 | antProject.addReference("maven.test.classpath", p);
139 |
140 | antProject.addReference("maven.plugin.classpath", getPathFromArtifacts(pluginArtifact, antProject));
141 |
142 | antProject.addReference(DEFAULT_MAVEN_PROJECT_REFID, project);
143 | antProject.addReference(DEFAULT_MAVEN_PROJECT_HELPER_REFID, projectHelper);
144 | initMavenTasks(antProject);
145 |
146 | copyProperties(project, antProject);
147 | copyProperties(model.getProperties(), antProject);
148 |
149 | return antProject;
150 |
151 | } catch (DependencyResolutionRequiredException e) {
152 | throw new MojoExecutionException("DependencyResolutionRequiredException: " + e.getMessage(), e);
153 | } catch (BuildException e) {
154 | throw new MojoExecutionException("An Ant BuildException has occurred: " + e.getMessage(), e);
155 | } catch (Throwable e) {
156 | throw new MojoExecutionException("Error executing ant tasks: " + e.getMessage(), e);
157 | }
158 | }
159 |
160 | private static void setupLogger(File antBuildFile, Log logger, Project antProject) throws FileNotFoundException {
161 | DefaultLogger consoleLogger = new DefaultLogger();
162 | consoleLogger.setOutputPrintStream(System.out);
163 | consoleLogger.setErrorPrintStream(System.err);
164 |
165 | addBuildListener(logger, antProject, consoleLogger);
166 |
167 | DefaultLogger fileLogger = new DefaultLogger();
168 | PrintStream ps = new PrintStream(new FileOutputStream(new File(antBuildFile.getAbsolutePath() + ".log")));
169 | fileLogger.setOutputPrintStream(ps);
170 | fileLogger.setErrorPrintStream(ps);
171 |
172 | addBuildListener(logger, antProject, fileLogger);
173 | }
174 |
175 | private static void addBuildListener(Log logger, Project antProject, DefaultLogger listener) {
176 | if (logger.isDebugEnabled()) {
177 | listener.setMessageOutputLevel(Project.MSG_DEBUG);
178 | } else if (logger.isInfoEnabled()) {
179 | listener.setMessageOutputLevel(Project.MSG_INFO);
180 | } else if (logger.isWarnEnabled()) {
181 | listener.setMessageOutputLevel(Project.MSG_WARN);
182 | } else if (logger.isErrorEnabled()) {
183 | listener.setMessageOutputLevel(Project.MSG_ERR);
184 | } else {
185 | listener.setMessageOutputLevel(Project.MSG_VERBOSE);
186 | }
187 | antProject.addBuildListener(listener);
188 | }
189 |
190 | private static void stringReplace(StringBuffer text, String match, String with) {
191 | int index = text.indexOf(match);
192 | if (index != -1) {
193 | text.replace(index, index + match.length(), with);
194 | }
195 | }
196 |
197 | private static Path getPathFromArtifacts(Collection artifacts, Project antProject)
198 | throws DependencyResolutionRequiredException {
199 | if (artifacts == null) {
200 | return new Path(antProject);
201 | }
202 |
203 | List list = new ArrayList(artifacts.size());
204 | for (Artifact a : artifacts) {
205 | File file = a.getFile();
206 | if (file == null) {
207 | throw new DependencyResolutionRequiredException(a);
208 | }
209 | list.add(file.getPath());
210 | }
211 |
212 | Path p = new Path(antProject);
213 | p.setPath(StringUtils.join(list.iterator(), File.pathSeparator));
214 |
215 | return p;
216 | }
217 |
218 | private static void initMavenTasks(Project antProject) {
219 | Typedef typedef = new Typedef();
220 | typedef.setProject(antProject);
221 | typedef.setResource(ANTLIB);
222 | typedef.execute();
223 | }
224 |
225 | private static void copyProperties(MavenProject mavenProject, Project antProject) {
226 | copyProperties(mavenProject.getProperties(), antProject);
227 |
228 | // Set the POM file as the ant.file for the tasks run directly in Maven.
229 | antProject.setProperty("ant.file", mavenProject.getFile().getAbsolutePath());
230 |
231 | // Add some of the common maven properties
232 | antProject.setProperty(("project.groupId"), mavenProject.getGroupId());
233 | antProject.setProperty(("project.artifactId"), mavenProject.getArtifactId());
234 | antProject.setProperty(("project.name"), mavenProject.getName());
235 | if (mavenProject.getDescription() != null) {
236 | antProject.setProperty(("project.description"), mavenProject.getDescription());
237 | }
238 | antProject.setProperty(("project.version"), mavenProject.getVersion());
239 | antProject.setProperty(("project.packaging"), mavenProject.getPackaging());
240 | antProject.setProperty(("project.build.directory"), mavenProject.getBuild().getDirectory());
241 | antProject.setProperty(("project.build.outputDirectory"), mavenProject.getBuild().getOutputDirectory());
242 | antProject.setProperty(("project.build.testOutputDirectory"), mavenProject.getBuild().getTestOutputDirectory());
243 | antProject.setProperty(("project.build.sourceDirectory"), mavenProject.getBuild().getSourceDirectory());
244 | antProject.setProperty(("project.build.testSourceDirectory"), mavenProject.getBuild().getTestSourceDirectory());
245 | }
246 |
247 | private static void copyProperties(Properties properties, Project antProject) {
248 | for (Object o : properties.keySet()) {
249 | String key = (String) o;
250 | antProject.setProperty(key, properties.getProperty(key));
251 | }
252 | }
253 | }
254 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
--------------------------------------------------------------------------------
/src/main/java/com/orctom/mojo/was/AbstractWASMojo.java:
--------------------------------------------------------------------------------
1 | package com.orctom.mojo.was;
2 |
3 | import com.orctom.was.model.WebSphereModel;
4 | import com.orctom.was.utils.PropertiesUtils;
5 | import org.apache.maven.artifact.Artifact;
6 | import org.apache.maven.plugin.AbstractMojo;
7 | import org.apache.maven.plugins.annotations.Component;
8 | import org.apache.maven.plugins.annotations.Parameter;
9 | import org.apache.maven.project.MavenProject;
10 | import org.apache.maven.project.MavenProjectHelper;
11 | import org.codehaus.plexus.configuration.PlexusConfiguration;
12 | import org.codehaus.plexus.util.StringUtils;
13 |
14 | import java.io.File;
15 | import java.util.*;
16 |
17 | /**
18 | * Abstract Mojo for websphere deployment
19 | * Created by CH on 3/4/14.
20 | */
21 | public abstract class AbstractWASMojo extends AbstractMojo {
22 |
23 | @Component
24 | protected MavenProject project;
25 |
26 | @Component
27 | protected MavenProjectHelper projectHelper;
28 |
29 | @Parameter(defaultValue = "${plugin.artifacts}")
30 | protected List pluginArtifacts;
31 |
32 | @Parameter(defaultValue = "${project.basedir}/was-maven-plugin.properties", property = "was.deploymentsPropertyFile")
33 | protected File deploymentsPropertyFile;
34 |
35 | @Parameter(required = true)
36 | protected String wasHome;
37 |
38 | @Parameter(defaultValue = "${project.build.finalName}")
39 | protected String applicationName;
40 |
41 | @Parameter(defaultValue = "localhost")
42 | protected String host;
43 |
44 | @Parameter
45 | protected String port;
46 |
47 | @Parameter
48 | protected String connectorType;
49 |
50 | @Parameter(defaultValue = "true")
51 | protected boolean restartAfterDeploy;
52 |
53 | /**
54 | * Required if target server is a cluster
55 | */
56 | @Parameter
57 | protected String cluster;
58 |
59 | @Parameter
60 | protected String cell;
61 |
62 | /**
63 | * Required if target server is NOT cluster
64 | */
65 | @Parameter
66 | protected String node;
67 |
68 | @Parameter
69 | protected String server;
70 |
71 | @Parameter
72 | protected String webservers;
73 |
74 | @Parameter
75 | protected String virtualHost;
76 |
77 | @Parameter
78 | protected String user;
79 |
80 | @Parameter
81 | protected String password;
82 |
83 | @Parameter
84 | protected String contextRoot;
85 |
86 | @Parameter
87 | protected String sharedLibs;
88 |
89 | @Parameter
90 | protected boolean parentLast;
91 |
92 | @Parameter
93 | protected boolean webModuleParentLast;
94 |
95 | @Parameter(defaultValue = "${project.artifact.file}")
96 | protected File packageFile;
97 |
98 | @Parameter(defaultValue = "false")
99 | protected boolean failOnError;
100 |
101 | @Parameter
102 | protected String script;
103 |
104 | @Parameter
105 | protected String scriptArgs;
106 |
107 | @Parameter
108 | protected String javaoption;
109 |
110 | @Parameter
111 | protected String deployOptions;
112 |
113 | @Parameter
114 | protected boolean verbose;
115 |
116 | /**
117 | * The XML for the Ant target.
118 | */
119 | @Parameter
120 | protected PlexusConfiguration[] preSteps;
121 |
122 | /**
123 | * The XML for the Ant target
124 | */
125 | @Parameter
126 | protected PlexusConfiguration[] postSteps;
127 |
128 | protected Set getWebSphereModels() {
129 | String deployTargets = System.getProperty(Constants.KEY_DEPLOY_TARGETS);
130 |
131 | if (StringUtils.isNotBlank(deployTargets)) {
132 | if (null != deploymentsPropertyFile && deploymentsPropertyFile.exists()) {
133 | Map propertiesMap = PropertiesUtils.loadSectionedProperties(deploymentsPropertyFile, getProjectProperties());
134 | if (null != propertiesMap && propertiesMap.size() >= 1) {
135 | getLog().info("Multi targets: " + deployTargets);
136 | return getWebSphereModels(deployTargets, propertiesMap);
137 | }
138 | }
139 |
140 | if (null == deploymentsPropertyFile) {
141 | getLog().info("Property config file: " + deploymentsPropertyFile + " not configured.");
142 | }
143 | if (!deploymentsPropertyFile.exists()) {
144 | getLog().info("Property config file: " + deploymentsPropertyFile + " doesn't exist.");
145 | }
146 | getLog().info("Single target not properly configured.");
147 | return null;
148 | } else {
149 | WebSphereModel model = getWebSphereModel();
150 | if (!model.isValid()) {
151 | getLog().info("Single target not properly configured. Missing 'cell' or 'cluster' or 'server' or 'node'");
152 | return null;
153 | }
154 | getLog().info("Single target: " + model.getHost());
155 | Set models = new HashSet(1);
156 | models.add(model);
157 | return models;
158 | }
159 | }
160 |
161 | protected WebSphereModel getWebSphereModel() {
162 | WebSphereModel model = new WebSphereModel()
163 | .setWasHome(wasHome)
164 | .setApplicationName(applicationName)
165 | .setHost(host)
166 | .setPort(port)
167 | .setConnectorType(connectorType)
168 | .setCluster(cluster)
169 | .setCell(cell)
170 | .setNode(node)
171 | .setServer(server)
172 | .setWebservers(webservers)
173 | .setVirtualHost(virtualHost)
174 | .setContextRoot(contextRoot)
175 | .setSharedLibs(sharedLibs)
176 | .setParentLast(parentLast)
177 | .setWebModuleParentLast(webModuleParentLast)
178 | .setUser(user)
179 | .setPassword(password)
180 | .setPackageFile(packageFile.getAbsolutePath())
181 | .setScript(script)
182 | .setScriptArgs(scriptArgs)
183 | .setJavaoption(javaoption)
184 | .setDeployOptions(deployOptions)
185 | .setFailOnError(failOnError)
186 | .setRestartAfterDeploy(restartAfterDeploy)
187 | .setVerbose(verbose);
188 |
189 | model.setProperties(getProjectProperties());
190 |
191 | return model;
192 | }
193 |
194 | protected Set getWebSphereModels(String deployTargetStr, Map propertiesMap) {
195 | Set deployTargets = new HashSet();
196 | Collections.addAll(deployTargets, StringUtils.split(deployTargetStr, ","));
197 |
198 | Set models = new HashSet();
199 | for (String deployTarget : deployTargets) {
200 | Properties props = propertiesMap.get(deployTarget);
201 | if (null == props || props.isEmpty()) {
202 | getLog().info("[SKIPPED] " + deployTarget + ", not configured in property file.");
203 | continue;
204 | }
205 |
206 | updateApplicationNameWithSuffix(props);
207 |
208 | WebSphereModel model = new WebSphereModel()
209 | .setWasHome(wasHome)
210 | .setApplicationName(getPropertyValue("applicationName", props))
211 | .setHost(getPropertyValue("host", props))
212 | .setPort(getPropertyValue("port", props))
213 | .setConnectorType(getPropertyValue("connectorType", props))
214 | .setCluster(getPropertyValue("cluster", props))
215 | .setCell(getPropertyValue("cell", props))
216 | .setNode(getPropertyValue("node", props))
217 | .setServer(getPropertyValue("server", props))
218 | .setWebservers(getPropertyValue("webservers", props))
219 | .setVirtualHost(getPropertyValue("virtualHost", props))
220 | .setContextRoot(getPropertyValue("contextRoot", props))
221 | .setSharedLibs(getPropertyValue("sharedLibs", props))
222 | .setParentLast(Boolean.valueOf(getPropertyValue("parentLast", props)))
223 | .setWebModuleParentLast(Boolean.valueOf(getPropertyValue("webModuleParentLast", props)))
224 | .setUser(getPropertyValue("user", props))
225 | .setPassword(getPropertyValue("password", props))
226 | .setPackageFile(packageFile.getAbsolutePath())
227 | .setScript(script)
228 | .setScriptArgs(scriptArgs)
229 | .setJavaoption(javaoption)
230 | .setDeployOptions(deployOptions)
231 | .setFailOnError(failOnError)
232 | .setRestartAfterDeploy(Boolean.valueOf(getPropertyValue("restartAfterDeploy", props)))
233 | .setVerbose(verbose);
234 |
235 | model.setProperties(props);
236 | if (model.isValid()) {
237 | models.add(model);
238 | }
239 | }
240 |
241 | return models;
242 | }
243 |
244 | private void updateApplicationNameWithSuffix(Properties props) {
245 | String appNameSuffix = getPropertyValue("applicationNameSuffix", props);
246 | if (StringUtils.isNotEmpty(appNameSuffix)) {
247 | String appName = getPropertyValue("applicationName", props);
248 | props.setProperty("applicationName", appName + "_" + appNameSuffix);
249 | }
250 | }
251 |
252 | protected String getPropertyValue(String propertyName, Properties props) {
253 | String value = props.getProperty(propertyName);
254 | if (isValueNotResolved(value)) {
255 | value = PropertiesUtils.resolve(value, props);
256 | props.setProperty(propertyName, value);
257 | }
258 | return value;
259 | }
260 |
261 | private boolean isValueNotResolved(String value) {
262 | return StringUtils.isNotEmpty(value) && value.contains("{{") && value.contains("}}");
263 | }
264 |
265 | private Properties getProjectProperties() {
266 | Properties properties = new Properties(project.getProperties());
267 | setProperty(properties, "applicationName", applicationName);
268 | setProperty(properties, "host", host);
269 | setProperty(properties, "port", port);
270 | setProperty(properties, "connectorType", connectorType);
271 | setProperty(properties, "cluster", cluster);
272 | setProperty(properties, "cell", cell);
273 | setProperty(properties, "node", node);
274 | setProperty(properties, "server", server);
275 | setProperty(properties, "webservers", webservers);
276 | setProperty(properties, "virtualHost", virtualHost);
277 | setProperty(properties, "user", user);
278 | setProperty(properties, "password", password);
279 | setProperty(properties, "contextRoot", contextRoot);
280 | setProperty(properties, "sharedLibs", sharedLibs);
281 | setProperty(properties, "parentLast", String.valueOf(parentLast));
282 | setProperty(properties, "webModuleParentLast", String.valueOf(webModuleParentLast));
283 | setProperty(properties, "packageFile", packageFile.getAbsolutePath());
284 | setProperty(properties, "javaoption", javaoption);
285 | setProperty(properties, "deployOptions", deployOptions);
286 | setProperty(properties, "failOnError", String.valueOf(failOnError));
287 | setProperty(properties, "script", script);
288 | setProperty(properties, "scriptArgs", scriptArgs);
289 | setProperty(properties, "verbose", String.valueOf(verbose));
290 | setProperty(properties, "restartAfterDeploy", String.valueOf(restartAfterDeploy));
291 |
292 | properties.setProperty("basedir", project.getBasedir().getAbsolutePath());
293 | properties.setProperty("project.basedir", project.getBasedir().getAbsolutePath());
294 | properties.setProperty("version", project.getVersion());
295 | properties.setProperty("project.version", project.getVersion());
296 | properties.setProperty("project.build.directory", project.getBuild().getDirectory());
297 | properties.setProperty("project.build.outputDirectory", project.getBuild().getOutputDirectory());
298 | properties.setProperty("project.build.finalName", project.getBuild().getFinalName());
299 | properties.setProperty("project.name", project.getName());
300 | properties.setProperty("groupId", project.getGroupId());
301 | properties.setProperty("project.groupId", project.getGroupId());
302 | properties.setProperty("artifactId", project.getArtifactId());
303 | properties.setProperty("project.artifactId", project.getArtifactId());
304 | return properties;
305 | }
306 |
307 | private void setProperty(Properties properties, String key, String value) {
308 | if (StringUtils.isNotEmpty(value)) {
309 | properties.setProperty(key, value);
310 | }
311 | }
312 | }
313 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # *was-maven-plugin* is looking for new maintainer
2 |
3 | # was-maven-plugin [](https://travis-ci.org/orctom/was-maven-plugin) [](https://maven-badges.herokuapp.com/maven-central/com.orctom.mojo/was-maven-plugin)
4 |
5 | - [Introduction](#introduction)
6 | - [How It Works](#how-it-works)
7 | - [Goal-`deploy`](#goal-deploy)
8 | - [Parameters](#parameters)
9 | - [Single Target Server](#single-target-server)
10 | - [Multi Target Servers](#multi-target-servers)
11 | - [Pre-Steps and Post-Steps](#pre-steps-and-post-steps)
12 | - [Customized Jython Script File](#customized-jython-script-file)
13 | - [Continues Deployment with Jenkins](#continues-deployment-with-jenkins)
14 | - [With Global Security Turned on](#with-global-security-turned-on)
15 | - [Change Log](#change-log)
16 |
17 | ## Introduction
18 | Maven plugin to deploy a single war or ear to one or multi local or remote WebSphere Application Server (WAS) at a single build.
19 | Tested on WAS 8.5
20 | **Requires: WebSphere Application Server installation on host box! But no need to be configured, nor running.**
21 |
22 | **Requires: JDK 6 or later**
23 |
24 | ## How It Works
25 | These are the known popular ways that you can programmly have your war/ear deployed to a running WebSphere Application Server:
26 | ### JMX
27 | Using IBM specialized JMX APIs you could not only retrieve the information of the apps, but also you can do deployment.
28 |
29 | 2 jars from WebSphere are required along with your build.
30 | * com.ibm.ws.admin.client_x.x.x.jar (over 50MB)
31 | * com.ibm.ws.orb_x.x.x.jar (about 2MB)
32 |
33 | **It does NOT support all options for deployment!**
34 |
35 | ### Monitored Directory Deployment
36 | Deployment by adding your packages to a `monitoredDeployableApps` subdirectory of an application server or deployment manager profile.
37 |
38 | For more information, please check:
39 | http://www-01.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/trun_app_install_dragdrop.html
40 |
41 | In order to deploy to a remote WAS, you'll have to copy/upload your packages to remote host first thru sftp or other approaches.
42 |
43 | **It's turned off by default.**
44 | ### Ant Tasks
45 | WebSphere provides a set of built-in ant tasks, by using which you could also programmly have your packages deployed to WAS.
46 |
47 | http://www-01.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/com/ibm/websphere/ant/tasks/package-summary.html
48 |
49 | **Ant tasks are in the end been translated to `jacl` script and been executed in `wsadmin` client.**
50 | ### wsadmin client (what we are using)
51 | wsadmin client tool is the most powerful and flexible tool from OPS' perspective, which locates in `$WAS_HOME/bin/wsadmin.sh`.
52 |
53 | It supports 2 scripting languages: jacl (default) and jython (recommended).
54 |
55 | It uses WebSphere built-in security (credencials) and file transfer protocal (no sftp is needed) for a remote deployment.
56 |
57 | **JMX and Ant Tasks approaches were also implemented in the beginning, but we had them removed before 1.0.2**
58 |
59 | ## Goal-`deploy`
60 | The only goal of this plugin, it will:
61 | 1. Check if an application with the same name already installed on target server(s)/cluster(s)
62 | * Uninstall it if yes
63 | 2. Install the package to target server(s)/cluster(s)
64 | 3. Restart target server(s)/cluster(s)
65 |
66 | ### Parameters
67 | | Name | Type | Description |
68 | | ------------------------- | --------- | --------------------------------------------------------------------------------------------------------- |
69 | | **wasHome** | String | WebSphere Application Server home. Default: `${env.WAS_HOME}`, **required** |
70 | | **applicationName** | String | Application name displayed in admin console. Default: `${project.build.finalName}` |
71 | | applicationNameSuffix | String | Will be appended to applicationName, as `applicationName_applicationNameSuffix`, **property file only** |
72 | | host | String | Local/Remote WAS IP/domain URL. e.g. `10.95.0.100`, `devtrunk01.company.com`, default: `localhost` |
73 | | port | String | Default: `8879` (when `cluster` not empty); `8880` (when `cluster` empty) |
74 | | connectorType | String | Default: `SOAP` |
75 | | cluster | String | Target cluster name, **required** if target WAS is a cluster |
76 | | cell | String | Target cell name |
77 | | node | String | Target node name, |
78 | | server | String | Target server name, |
79 | | webservers | String | Target web server(s) name, comma-separated. |
80 | | virtualHost | String | Target virtual host name |
81 | | user | String | Account username for **target WAS** admin console, if global security is turned on |
82 | | password | String | Account password for **target WAS** admin console, if global security is turned on |
83 | | contextRoot | String | **required** for war deployment |
84 | | sharedLibs | String | Bind the exist shared libs to ear/war, comma-separated (,) |
85 | | parentLast | Boolean | `true` to set classloader mode of application to `PARENT_LAST`, default `false` |
86 | | restartAfterDeploy | Boolean | `true` to restart server after deploy, `false` to start application directly. Default `true` |
87 | | webModuleParentLast | Boolean | `true` to set classloader mode of web module to `PARENT_LAST`, default `false` |
88 | | **packageFile** | String | The EAR/WAR package that will be deployed to remote RAS, Default: `${project.artifact.file}` |
89 | | **failOnError** | Boolean | Default: `false` Whether failed the build when failed to deploy. |
90 | | **verbose** | Boolean | Whether show more detailed info in log |
91 | | **script** | String | Your own jython script for deployment. Double braces for variables, such as: `{{cluster}}` |
92 | | **scriptArgs** | String | Args that will be passed to the `script` |
93 | | **javaoption** | String | Sample `-Xmx1024m`, `-Xms512m -Xmx1024m` |
94 | | deployOptions | String | Sample `-precompileJSPs`, `-precompileJSPs -deployws` |
95 | | **preSteps** | Ant tasks | Ant tasks that can be executed before the deployments |
96 | | **postSteps** | Ant tasks | Ant tasks that can be executed after the deployments |
97 | | deploymentsPropertyFile | File | For multi target, hold above parameters, except those in **bold**. Default: `was-maven-plugin.properties` |
98 |
99 | Generally, you need to specify at least
100 | * `cluster` for a cluster
101 | * `server` and `node` for a non-cluster
102 |
103 | ## Single Target Server
104 | ```xml
105 |
106 | com.orctom.mojo
107 | was-maven-plugin
108 | ${latest-version}
109 |
110 |
111 | deploy
112 | install
113 |
114 | deploy
115 |
116 |
117 | ${env.WAS_HOME}
118 | ${project.build.finalName}
119 | localhost
120 | server01
121 | node01
122 | default_host
123 | true
124 |
125 |
126 |
127 |
128 | ```
129 |
130 | ## Multi Target Servers
131 | #### was-maven-plugin.properties
132 | This property file contains the meta config for target WAS.
133 | The section name will be used to identify each target WAS.
134 |
135 | **Please put `was-maven-plugin.properties` to the same folder as `pom.xml`, to make it available as `${project.basedir}/was-maven-plugin.properties`**
136 |
137 | ```properties
138 | [DEFAULT]
139 | virtualHost=default_host
140 |
141 | [dev-trunk1]
142 | host=devtrunk1.company.com
143 | applicationNameSuffix=trunk1
144 | cluster=cluster01
145 | server=server01
146 |
147 | [dev-trunk2]
148 | host=devtrunk2.company.com
149 | applicationNameSuffix=trunk2
150 | cluster=cluster02
151 | server=server02
152 |
153 | [dev-trunk3]
154 | host=devtrunk3.company.com
155 | applicationNameSuffix=trunk3
156 | cluster=cluster03
157 | server=server03
158 | virtualHost=devtrunk3_host
159 | ```
160 |
161 | #### pom.xml
162 | ```xml
163 |
164 | com.orctom.mojo
165 | was-maven-plugin
166 | ${latest-version}
167 |
168 |
169 | deploy
170 | install
171 |
172 | deploy
173 |
174 |
175 | ${env.WAS_HOME}
176 | true
177 |
178 |
179 |
180 |
181 | ```
182 | **Deploy to `dev-trunk1` and `dev-trunk2`**
183 | ```
184 | mvn clean install -Ddeploy_targets=`dev-trunk1`,`dev-trunk2`
185 | ```
186 | **Deploy to `dev-trunk2` and `dev-trunk3`**
187 | ```
188 | mvn clean install -Ddeploy_targets=`dev-trunk2`,`dev-trunk3`
189 | ```
190 |
191 | ## Pre-Steps and Post-Steps
192 | ```xml
193 |
194 | com.orctom.mojo
195 | was-maven-plugin
196 | ${latest-version}
197 |
198 |
199 | deploy
200 | install
201 |
202 | deploy
203 |
204 |
205 | ${env.WAS_HOME}
206 | true
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 | ant-contrib
230 | ant-contrib
231 | 20020829
232 |
233 |
234 | org.apache.ant
235 | ant-jsch
236 | 1.8.4
237 |
238 |
239 | com.jcraft
240 | jsch
241 | 0.1.49
242 |
243 |
244 |
245 | ```
246 | * **pre-steps/post-steps can be used with both single target server and multi target servers**
247 | * **All properties defined in properties section of pom or in was-maven-plugin.properties are available in pre-steps/post-steps ant tasks**
248 |
249 | ## Customized Jython Script File
250 | This plugin also supports customized jython script if you need to tween the installation options, such server mappings.
251 |
252 | You can copy-create it from [the built-in one](https://github.com/orctom/was-util/blob/master/src/main/resources/jython/websphere.py),
253 | or write a totally different one of you own.
254 |
255 | Double braces for variables, such as: `{{cluster}}`, properties in was-maven-plugin.properties are all available as variables.
256 | ```xml
257 |
258 | com.orctom.mojo
259 | was-maven-plugin
260 | ${latest-version}
261 |
262 |
263 | deploy
264 | install
265 |
266 | deploy
267 |
268 |
269 | ${env.WAS_HOME}
270 |
271 | optional-args
272 | true
273 |
274 |
275 |
276 |
277 | ```
278 |
279 | ## Continues Deployment with Jenkins
280 | We could move this plugin to a profile, and utilize [Extended Choice Parameter plugin](https://wiki.jenkins-ci.org/display/JENKINS/Extended+Choice+Parameter+plugin) to make this parameterized.
281 |
282 | #### Sample pom.xml
283 | ```xml
284 |
285 |
286 | deploy
287 |
288 |
289 | deploy
290 | true
291 |
292 |
293 |
294 |
295 |
296 | com.orctom.mojo
297 | was-maven-plugin
298 | ${latest-version}
299 |
300 |
301 | deploy
302 | install
303 |
304 | deploy
305 |
306 |
307 | ${env.WAS_HOME}
308 | true
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 | ant-contrib
351 | ant-contrib
352 | 20020829
353 |
354 |
355 | org.apache.ant
356 | ant-jsch
357 | 1.8.4
358 |
359 |
360 | com.jcraft
361 | jsch
362 | 0.1.49
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 | ```
371 | #### Sample Jenkins Job Configuration
372 | **Configure**
373 |
374 | 
375 |
376 | **Trigger**
377 |
378 | 
379 |
380 | ## With Global Security Turned on
381 | When Global Security is enabled on remote WAS (not under a same deployment manager), certificates of remote WAS need to be added to local trust store.
382 | We could configure WAS to prompt to add them to local trust store.
383 | 1. Open ${WAS_HOME}/properties/ssl.client.props
384 | 2. Change the value of `com.ibm.ssl.enableSignerExchangePrompt` to `gui` or `stdin`
385 |
386 | * `gui`: will prompt a Java based window, this requires a X window installed.
387 | * `stdin`: when using ssh, or on client linux without X window installed.
388 |
389 | ## Change Log
390 |
391 | #### 1.1.3.3
392 | * Added system property support for defining the deployments property file. [#19](https://github.com/orctom/was-maven-plugin/pull/19)
393 |
394 | #### 1.1.3.2
395 | * Added support for IHS webserver mapping for standalone WAS.
396 |
397 | #### 1.1.3.1
398 | * Fixed issue [multi shared libs only the last one got bound](https://github.com/orctom/was-maven-plugin/issues/13)
399 |
400 | #### 1.1.2
401 | * Fixed issue for workspace path includes whitespaces.
402 |
403 | #### 1.1.1
404 | * Fixed issue of not starting application on standalone WAS (restartAfterDeploy=false)
405 |
406 | #### 1.1.0
407 | * Fixed server mapping issue with cluster. Apps will be deployed to all servers that managed by the specified cluster.
408 | * Web servers support, use `webservers` to specify the web server(s) that you want to bind. (but you still have to 'update web server plug-in configuration' by your self.)
409 | * Added parameter `deployOptions`, expecting space-separated options such as `-precompileJSPs -deployws`, which will be prepended in the deployment options.
410 | * Fixed issue about `failOnError`.
411 | * Extracted some common code including `websphere.py` to [was-util](https://github.com/orctom/was-util), which is also been used by [was-gradle-plugin](https://github.com/orctom/was-gradle-plugin)
412 |
413 | #### 1.0.12
414 | * Fixed the issue about "Template 'jython\websphere.py' not found" specific for Windows.
415 |
416 | #### 1.0.11
417 | * Fixed the issue with customized script.
418 |
419 | #### 1.0.10
420 | * Added a boolean parameter `restartAfterDeploy`:
421 | - `true` to restart server after deploy
422 | - `false` to start application directly
423 | - Default: `true`
424 |
425 | #### 1.0.9
426 | * Added support to override default `javaoption` in wsadmin client, in case you get `OutOfMemoryError`.
427 |
428 | #### 1.0.8
429 | * Fixed single target WAS deployment issue.
430 | * Not to check whether parent folder of deployment script been created or not.
431 |
432 | #### 1.0.7
433 | * Removed `preCompileJSPs` options for deployment.
434 |
435 | #### 1.0.6
436 | * Fixed multi-server deployment issue.
437 |
438 | #### 1.0.5
439 | * Downgraded to use 1.5 build level, so that it can be used for older version of websphere.
440 | * Fixed property resolving issue, properties in was-maven-plugin.properties are all available in custome scripts and pre/post steps.
441 |
442 | #### 1.0.4
443 | * Added `PARENT_LAST` for application and web module and `shared libs` bindings.
444 | * Added `failonerror`
445 |
446 | #### 1.0.3
447 | * Removed private project specific logic. (it's the 1st working version for general projects for websphere deployment).
448 |
--------------------------------------------------------------------------------