diff --git a/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc b/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc
index 16092882a20..707e50c3ab4 100644
--- a/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc
+++ b/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc
@@ -607,11 +607,155 @@ further information.
+[[build-tool-plugins-antlib]]
+== Spring Boot AntLib module
+The Spring Boot AntLib module provides basic Spring Boot support for Apache Ant. You can
+use the module to create executable jars. To use the module you need to declare an
+additional `spring-boot` namespace in your `build.xml`:
+
+[source,xml,indent=0]
+----
+
+ ...
+
+----
+
+You'll need to remember to start Ant using the `-lib` option, for example:
+
+[indent=0,subs="verbatim,quotes,attributes"]
+----
+ $ ant -lib
+----
+
+TIP: The "`Using Spring Boot`" section includes a more complete example of
+<>
+
+
+=== Spring Boot Ant tasks
+Once the `spring-boot-antlib` namespace has been declared, the following additional
+tasks are available.
+
+
+
+==== spring-boot:exejar
+The `exejar` task can be used to creates a Spring Boot executable jar. The following
+attributes are supported by the task:
+
+[cols="1,2,2"]
+|====
+|Attribute |Description |Required
+
+|`destfile`
+|The destination jar file to create
+|Yes
+
+|`classes`
+|The root directory of Java classfiles
+|Yes
+
+|`start-class`
+|The main application class to run
+|No _(default is first class found declaring a `main` method)_
+|====
+
+The following nested elements can be used with the task:
+
+[cols="1,4"]
+|====
+|Element |Description
+
+|`resources`
+|One or more {ant-manual}/Types/resources.html#collection[Resource Collections]
+describing a set of {ant-manual}/Types/resources.html[Resources] that should be added to
+the content of the created +jar+ file.
+
+|`lib`
+|One or more {ant-manual}/Types/resources.html#collection[Resource Collections]
+that should be added to the set of jar libraries that make up the runtime dependency
+classpath of the application.
+|====
+
+
+
+===== Examples
+.Specify +start-class+
+[source,xml,indent=0]
+----
+
+
+
+
+
+
+
+
+----
+
+.Detect +start-class+
+[source,xml,indent=0]
+----
+
+
+
+
+
+----
+
+
+
+=== spring-boot:findmainclass
+The `findmainclass` task is used internally by `exejar` to locate a class declaring a
+`main`. You can also use this task directly in your build if needed. The following
+attributes are supported
+
+[cols="1,2,2"]
+|====
+|Attribute |Description |Required
+
+|`classesroot`
+|The root directory of Java classfiles
+|Yes _(unless `mainclass` is specified)_
+
+|`mainclass`
+|Can be used to short-circuit the `main` class search
+|No
+
+|`property`
+|The Ant property that should be set with the result
+|No _(result will be logged if unspecified)_
+|====
+
+
+
+===== Examples
+.Find and log
+[source,xml,indent=0]
+----
+
+----
+
+.Find and set
+[source,xml,indent=0]
+----
+
+----
+
+.Override and set
+[source,xml,indent=0]
+----
+
+----
+
+
+
[[build-tool-plugins-other-build-systems]]
== Supporting other build systems
-If you want to use a build tool other than Maven or Gradle, you will likely need to develop
-your own plugin. Executable jars need to follow a specific format and certain entries need
-to be written in an uncompressed form (see the
+If you want to use a build tool other than Maven, Gradle or Ant, you will likely need to
+develop your own plugin. Executable jars need to follow a specific format and certain
+entries need to be written in an uncompressed form (see the
_<>_ section
in the appendix for details).
@@ -668,6 +812,8 @@ Here is a typical example repackage:
});
----
+
+
[[build-tool-plugins-whats-next]]
== What to read next
If you're interested in how the build tool plugins work you can
diff --git a/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-docs/src/main/asciidoc/howto.adoc
index fd3f141bbbd..b8124aa2449 100644
--- a/spring-boot-docs/src/main/asciidoc/howto.adoc
+++ b/spring-boot-docs/src/main/asciidoc/howto.adoc
@@ -2198,9 +2198,10 @@ details.
[[howto-build-an-executable-archive-with-ant]]
-=== Build an executable archive with Ant
+=== Build an executable archive from Ant without using spring-boot-antlib
To build with Ant you need to grab dependencies, compile and then create a jar or war
-archive as normal. To make it executable:
+archive as normal. To make it executable you can either use the `spring-boot-antlib`
+module, or you can follow these instructions:
. Use the appropriate launcher as a `Main-Class`, e.g. `JarLauncher` for a jar file, and
specify the other properties it needs as manifest entries, principally a `Start-Class`.
@@ -2236,7 +2237,7 @@ The Actuator Sample has a `build.xml` that should work if you run it with
[indent=0,subs="verbatim,quotes,attributes"]
----
- $ ant -lib /ivy-2.2.jar
+ $ ant -lib
----
after which you can run the application with
diff --git a/spring-boot-docs/src/main/asciidoc/index.adoc b/spring-boot-docs/src/main/asciidoc/index.adoc
index c2d0483bf53..d805cba5af9 100644
--- a/spring-boot-docs/src/main/asciidoc/index.adoc
+++ b/spring-boot-docs/src/main/asciidoc/index.adoc
@@ -39,6 +39,7 @@ Phillip Webb; Dave Syer; Josh Long; Stéphane Nicoll; Rob Winch; Andy Wilkinson;
:spring-data-mongo-javadoc: http://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb
:spring-data-rest-javadoc: http://docs.spring.io/spring-data/rest/docs/current/api/org/springframework/data/rest
:gradle-userguide: http://www.gradle.org/docs/current/userguide
+:ant-manual: http://ant.apache.org/manual
// ======================================================================================
include::documentation-overview.adoc[]
diff --git a/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc b/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
index ed074d49c42..c1c6c10885d 100644
--- a/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
+++ b/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
@@ -210,12 +210,68 @@ endif::[]
[[using-boot-ant]]
=== Ant
-It is possible to build a Spring Boot project using Apache Ant, however, no special
-support or plugins are provided. Ant scripts can use the Ivy dependency system to import
-starter POMs.
+It is possible to build a Spring Boot project using Apache Ant+Ivy. The
+`spring-boot-antlib` "`AntLib`" module is also available to help Ant create executable
+jars.
-See the _<>_ "`How-to`" for more
-complete instructions.
+To declare dependencies a typical `ivy.xml` file will look something like this:
+
+[source,xml,indent=0]
+----
+
+
+
+
+
+
+
+
+
+
+----
+
+A typical `build.xml` will look like this:
+
+[source,xml,indent=0]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+TIP: See the _<>_ "`How-to`" if
+you don't want to use the `spring-boot-antlib` module.
diff --git a/spring-boot-tools/pom.xml b/spring-boot-tools/pom.xml
index dbd6e76065f..370869d27d4 100644
--- a/spring-boot-tools/pom.xml
+++ b/spring-boot-tools/pom.xml
@@ -25,5 +25,6 @@
spring-boot-loader-tools
spring-boot-maven-plugin
spring-boot-gradle-plugin
+ spring-boot-antlib
diff --git a/spring-boot-tools/spring-boot-antlib/pom.xml b/spring-boot-tools/spring-boot-antlib/pom.xml
new file mode 100644
index 00000000000..a3500a2ab50
--- /dev/null
+++ b/spring-boot-tools/spring-boot-antlib/pom.xml
@@ -0,0 +1,133 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-tools
+ 1.3.0.BUILD-SNAPSHOT
+
+ spring-boot-antlib
+ Spring Boot Antlib
+ Spring Boot Antlib
+ http://projects.spring.io/spring-boot/
+
+ Pivotal Software, Inc.
+ http://www.spring.io
+
+
+ ${basedir}/../..
+ 1.9.3
+
+
+
+ org.springframework.boot
+ spring-boot-loader
+ provided
+
+
+ org.springframework.boot
+ spring-boot-loader-tools
+ compile
+
+
+ org.apache.ant
+ ant
+ ${ant.version}
+ provided
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+
+
+
+ org.springframework.boot:spring-boot-loader-tools
+ org.springframework:spring-core
+
+
+ true
+ false
+ true
+
+
+
+ shade-runtime-dependencies
+ package
+
+ shade
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+
+
+ antunit
+ integration-test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ run
+
+
+
+
+
+ org.apache.ant
+ ant
+ ${ant.version}
+
+
+ org.apache.ant
+ ant-launcher
+ ${ant.version}
+
+
+ org.apache.ant
+ ant-antunit
+ 1.3
+
+
+ org.apache.ivy
+ ivy
+ 2.4.0
+
+
+ org.eclipse.jdt.core.compiler
+ ecj
+ 4.4.2
+
+
+
+
+
+
diff --git a/spring-boot-tools/spring-boot-antlib/src/it/sample/build.xml b/spring-boot-tools/spring-boot-antlib/src/it/sample/build.xml
new file mode 100644
index 00000000000..c6992bb33ec
--- /dev/null
+++ b/spring-boot-tools/spring-boot-antlib/src/it/sample/build.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Checking @{jar}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-boot-tools/spring-boot-antlib/src/it/sample/ivysettings.xml b/spring-boot-tools/spring-boot-antlib/src/it/sample/ivysettings.xml
new file mode 100644
index 00000000000..72631b8ba83
--- /dev/null
+++ b/spring-boot-tools/spring-boot-antlib/src/it/sample/ivysettings.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-boot-tools/spring-boot-antlib/src/it/sample/src/main/java/org/test/SampleApplication.java b/spring-boot-tools/spring-boot-antlib/src/it/sample/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 00000000000..3b04532758d
--- /dev/null
+++ b/spring-boot-tools/spring-boot-antlib/src/it/sample/src/main/java/org/test/SampleApplication.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2012-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.test;
+
+import org.joda.time.LocalDate;
+
+public class SampleApplication {
+
+ public static void main(String[] args) {
+ System.out.println(LocalDate.class.getSimpleName());
+ }
+
+}
+
diff --git a/spring-boot-tools/spring-boot-antlib/src/it/sample/src/main/resources/foo b/spring-boot-tools/spring-boot-antlib/src/it/sample/src/main/resources/foo
new file mode 100644
index 00000000000..b7d6715e2df
--- /dev/null
+++ b/spring-boot-tools/spring-boot-antlib/src/it/sample/src/main/resources/foo
@@ -0,0 +1 @@
+FOO
diff --git a/spring-boot-tools/spring-boot-antlib/src/main/java/org/springframework/boot/ant/FindMainClass.java b/spring-boot-tools/spring-boot-antlib/src/main/java/org/springframework/boot/ant/FindMainClass.java
new file mode 100644
index 00000000000..b88b343acd1
--- /dev/null
+++ b/spring-boot-tools/spring-boot-antlib/src/main/java/org/springframework/boot/ant/FindMainClass.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.ant;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.jar.JarFile;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.springframework.boot.loader.tools.MainClassFinder;
+import org.springframework.util.StringUtils;
+
+/**
+ * Ant task to find a main class.
+ *
+ * @author Matt Benson
+ * @since 1.3.0
+ */
+public class FindMainClass extends Task {
+
+ private String mainClass;
+
+ private File classesRoot;
+
+ private String property;
+
+ public FindMainClass(Project project) {
+ setProject(project);
+ }
+
+ @Override
+ public void execute() throws BuildException {
+ String mainClass = this.mainClass;
+ if (!StringUtils.hasText(mainClass)) {
+ mainClass = findMainClass();
+ if (!StringUtils.hasText(mainClass)) {
+ throw new BuildException(
+ "Could not determine main class given @classesRoot "
+ + this.classesRoot);
+ }
+ }
+ handle(mainClass);
+ }
+
+ private String findMainClass() {
+ if (this.classesRoot == null) {
+ throw new BuildException(
+ "one of @mainClass or @classesRoot must be specified");
+ }
+ if (!this.classesRoot.exists()) {
+ throw new BuildException("@classesRoot " + this.classesRoot
+ + " does not exist");
+ }
+ try {
+ if (this.classesRoot.isDirectory()) {
+ return MainClassFinder.findSingleMainClass(this.classesRoot);
+ }
+ return MainClassFinder
+ .findSingleMainClass(new JarFile(this.classesRoot), "/");
+ }
+ catch (IOException ex) {
+ throw new BuildException(ex);
+ }
+ }
+
+ private void handle(String mainClass) {
+ if (StringUtils.hasText(this.property)) {
+ getProject().setProperty(this.property, mainClass);
+ }
+ else {
+ log("Found main class " + mainClass);
+ }
+ }
+
+ /**
+ * Set the main class, which will cause the search to be bypassed.
+ * @param mainClass
+ */
+ public void setMainClass(String mainClass) {
+ this.mainClass = mainClass;
+ }
+
+ /**
+ * Set the root location of classes to be searched.
+ * @param classesRoot
+ */
+ public void setClassesRoot(File classesRoot) {
+ this.classesRoot = classesRoot;
+ }
+
+ /**
+ * Set the property to set (if unset, result will be printed to the log).
+ * @param property
+ */
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-antlib/src/main/java/org/springframework/boot/ant/ShareAntlibLoader.java b/spring-boot-tools/spring-boot-antlib/src/main/java/org/springframework/boot/ant/ShareAntlibLoader.java
new file mode 100644
index 00000000000..d00149c1b72
--- /dev/null
+++ b/spring-boot-tools/spring-boot-antlib/src/main/java/org/springframework/boot/ant/ShareAntlibLoader.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.ant;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.springframework.util.StringUtils;
+
+/**
+ * Quiet task that establishes a reference to its loader.
+ *
+ * @author Matt Benson
+ * @since 1.3.0
+ */
+public class ShareAntlibLoader extends Task {
+
+ private String refid;
+
+ public ShareAntlibLoader(Project project) {
+ super();
+ setProject(project);
+ }
+
+ @Override
+ public void execute() throws BuildException {
+ if (!StringUtils.hasText(this.refid)) {
+ throw new BuildException("@refid has no text");
+ }
+ getProject().addReference(this.refid, getClass().getClassLoader());
+ }
+
+ public void setRefid(String refid) {
+ this.refid = refid;
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-antlib/src/main/resources/org/springframework/boot/ant/antlib.xml b/spring-boot-tools/spring-boot-antlib/src/main/resources/org/springframework/boot/ant/antlib.xml
new file mode 100644
index 00000000000..21237dc4ec1
--- /dev/null
+++ b/spring-boot-tools/spring-boot-antlib/src/main/resources/org/springframework/boot/ant/antlib.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Using start class ${start-class}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Using destination directory ${destdir}
+
+
+ Extracting spring-boot-loader to ${destdir}/dependency
+
+
+
+
+
+ Embedding spring-boot-loader v${spring-boot.version}...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+