mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Isolate Aether in a separate class loader
Prior to this commit, the Aether-based GrapeEngine was loaded in the same class loader as the rest of Boot. This led to Aether's and its dependencies' types polluting the application's class path. Most notably, this caused problems with logging as the logging framework could be permaturely initialized. This commit isolates AetherGrapeEngine, Aether and its dependencies into a separate class loader. This is done by customizing the packaging of the CLI's jar file with the internal directory housing all of the types that will be loaded by the separate class loader.
This commit is contained in:
parent
39e8e46e2a
commit
c0ae78f3ec
1
pom.xml
1
pom.xml
@ -37,6 +37,7 @@
|
|||||||
<module>spring-boot-actuator</module>
|
<module>spring-boot-actuator</module>
|
||||||
<module>spring-boot-starters</module>
|
<module>spring-boot-starters</module>
|
||||||
<module>spring-boot-cli</module>
|
<module>spring-boot-cli</module>
|
||||||
|
<module>spring-boot-cli-grape</module>
|
||||||
<module>spring-boot-integration-tests</module>
|
<module>spring-boot-integration-tests</module>
|
||||||
</modules>
|
</modules>
|
||||||
</profile>
|
</profile>
|
||||||
|
175
spring-boot-cli-grape/pom.xml
Normal file
175
spring-boot-cli-grape/pom.xml
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-parent</artifactId>
|
||||||
|
<version>0.5.0.BUILD-SNAPSHOT</version>
|
||||||
|
<relativePath>../spring-boot-parent</relativePath>
|
||||||
|
</parent>
|
||||||
|
<artifactId>spring-boot-cli-grape</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<properties>
|
||||||
|
<main.basedir>${basedir}/..</main.basedir>
|
||||||
|
<start-class>org.springframework.boot.cli.SpringCli</start-class>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<!-- Provided -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.groovy</groupId>
|
||||||
|
<artifactId>groovy</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- Compile -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
<version>1.1.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven</groupId>
|
||||||
|
<artifactId>maven-aether-provider</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>org.eclipse.sisu.plexus</artifactId>
|
||||||
|
<groupId>org.eclipse.sisu</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.aether</groupId>
|
||||||
|
<artifactId>aether-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.aether</groupId>
|
||||||
|
<artifactId>aether-connector-basic</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.aether</groupId>
|
||||||
|
<artifactId>aether-impl</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.aether</groupId>
|
||||||
|
<artifactId>aether-spi</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.aether</groupId>
|
||||||
|
<artifactId>aether-transport-file</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.aether</groupId>
|
||||||
|
<artifactId>aether-transport-http</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>jcl-over-slf4j</artifactId>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.aether</groupId>
|
||||||
|
<artifactId>aether-util</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- Test -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<classpathDependencyExcludes>
|
||||||
|
<classpathDependencyExcludes>org.springframework:spring-core</classpathDependencyExcludes>
|
||||||
|
<classpathDependencyExcludes>org.springframework:spring-beans</classpathDependencyExcludes>
|
||||||
|
<classpathDependencyExcludes>org.springframework:spring-aop</classpathDependencyExcludes>
|
||||||
|
<classpathDependencyExcludes>org.springframework:spring-tx</classpathDependencyExcludes>
|
||||||
|
<classpathDependencyExcludes>org.springframework:spring-expression</classpathDependencyExcludes>
|
||||||
|
<classpathDependencyExcludes>org.springframework:spring-context</classpathDependencyExcludes>
|
||||||
|
<classpathDependencyExcludes>org.springframework:spring-test</classpathDependencyExcludes>
|
||||||
|
<classpathDependencyExcludes>org.springframework.retry:spring-retry</classpathDependencyExcludes>
|
||||||
|
<classpathDependencyExcludes>org.springframework.integration:spring-integration-core</classpathDependencyExcludes>
|
||||||
|
<classpathDependencyExcludes>org.springframework.integration:spring-integration-dsl-groovy-core</classpathDependencyExcludes>
|
||||||
|
</classpathDependencyExcludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<filters>
|
||||||
|
<filter>
|
||||||
|
<artifact>*:*</artifact>
|
||||||
|
<excludes>
|
||||||
|
<exclude>META-INF/*.SF</exclude>
|
||||||
|
<exclude>META-INF/*.DSA</exclude>
|
||||||
|
<exclude>META-INF/*.RSA</exclude>
|
||||||
|
</excludes>
|
||||||
|
</filter>
|
||||||
|
</filters>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<transformers>
|
||||||
|
<transformer
|
||||||
|
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
|
||||||
|
<transformer
|
||||||
|
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
|
<mainClass>${start-class}</mainClass>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.eclipse.m2e</groupId>
|
||||||
|
<artifactId>lifecycle-mapping</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<configuration>
|
||||||
|
<lifecycleMappingMetadata>
|
||||||
|
<pluginExecutions>
|
||||||
|
<pluginExecution>
|
||||||
|
<pluginExecutionFilter>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<versionRange>[1.7,)</versionRange>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
</pluginExecutionFilter>
|
||||||
|
<action>
|
||||||
|
<execute/>
|
||||||
|
</action>
|
||||||
|
</pluginExecution>
|
||||||
|
</pluginExecutions>
|
||||||
|
</lifecycleMappingMetadata>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
<pluginRepositories>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>objectstyle</id>
|
||||||
|
<name>ObjectStyle.org Repository</name>
|
||||||
|
<url>http://objectstyle.org/maven2/</url>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</pluginRepository>
|
||||||
|
</pluginRepositories>
|
||||||
|
</project>
|
@ -17,6 +17,7 @@
|
|||||||
package org.springframework.boot.cli.compiler;
|
package org.springframework.boot.cli.compiler;
|
||||||
|
|
||||||
import groovy.grape.GrapeEngine;
|
import groovy.grape.GrapeEngine;
|
||||||
|
import groovy.lang.GroovyClassLoader;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
@ -52,8 +53,6 @@ import org.eclipse.aether.resolution.DependencyRequest;
|
|||||||
import org.eclipse.aether.resolution.DependencyResult;
|
import org.eclipse.aether.resolution.DependencyResult;
|
||||||
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
|
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
|
||||||
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
|
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
|
||||||
import org.eclipse.aether.spi.log.Logger;
|
|
||||||
import org.eclipse.aether.spi.log.LoggerFactory;
|
|
||||||
import org.eclipse.aether.transfer.AbstractTransferListener;
|
import org.eclipse.aether.transfer.AbstractTransferListener;
|
||||||
import org.eclipse.aether.transfer.TransferCancelledException;
|
import org.eclipse.aether.transfer.TransferCancelledException;
|
||||||
import org.eclipse.aether.transfer.TransferEvent;
|
import org.eclipse.aether.transfer.TransferEvent;
|
||||||
@ -78,13 +77,13 @@ public class AetherGrapeEngine implements GrapeEngine {
|
|||||||
|
|
||||||
private static final String DEPENDENCY_VERSION = "version";
|
private static final String DEPENDENCY_VERSION = "version";
|
||||||
|
|
||||||
private final ProgressReporter progressReporter = new ProgressReporter();
|
private final Artifact parentArtifact;
|
||||||
|
|
||||||
private final ArtifactCoordinatesResolver artifactCoordinatesResolver;
|
private final ProgressReporter progressReporter = new ProgressReporter();
|
||||||
|
|
||||||
private final ArtifactDescriptorReader artifactDescriptorReader;
|
private final ArtifactDescriptorReader artifactDescriptorReader;
|
||||||
|
|
||||||
private final ExtendedGroovyClassLoader defaultClassLoader;
|
private final GroovyClassLoader defaultClassLoader;
|
||||||
|
|
||||||
private final RepositorySystemSession repositorySystemSession;
|
private final RepositorySystemSession repositorySystemSession;
|
||||||
|
|
||||||
@ -92,14 +91,14 @@ public class AetherGrapeEngine implements GrapeEngine {
|
|||||||
|
|
||||||
private final List<RemoteRepository> repositories;
|
private final List<RemoteRepository> repositories;
|
||||||
|
|
||||||
public AetherGrapeEngine(ExtendedGroovyClassLoader classLoader,
|
public AetherGrapeEngine(GroovyClassLoader classLoader, String parentGroupId,
|
||||||
ArtifactCoordinatesResolver artifactCoordinatesResolver) {
|
String parentArtifactId, String parentVersion) {
|
||||||
this.defaultClassLoader = classLoader;
|
this.defaultClassLoader = classLoader;
|
||||||
this.artifactCoordinatesResolver = artifactCoordinatesResolver;
|
this.parentArtifact = new DefaultArtifact(parentGroupId, parentArtifactId, "pom",
|
||||||
|
parentVersion);
|
||||||
|
|
||||||
DefaultServiceLocator mavenServiceLocator = MavenRepositorySystemUtils
|
DefaultServiceLocator mavenServiceLocator = MavenRepositorySystemUtils
|
||||||
.newServiceLocator();
|
.newServiceLocator();
|
||||||
mavenServiceLocator.setService(LoggerFactory.class, NopLoggerFactory.class);
|
|
||||||
mavenServiceLocator.addService(RepositorySystem.class,
|
mavenServiceLocator.addService(RepositorySystem.class,
|
||||||
DefaultRepositorySystem.class);
|
DefaultRepositorySystem.class);
|
||||||
|
|
||||||
@ -166,8 +165,7 @@ public class AetherGrapeEngine implements GrapeEngine {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
List<File> files = resolve(dependencies);
|
List<File> files = resolve(dependencies);
|
||||||
ExtendedGroovyClassLoader classLoader = (ExtendedGroovyClassLoader) args
|
GroovyClassLoader classLoader = (GroovyClassLoader) args.get("classLoader");
|
||||||
.get("classLoader");
|
|
||||||
if (classLoader == null) {
|
if (classLoader == null) {
|
||||||
classLoader = this.defaultClassLoader;
|
classLoader = this.defaultClassLoader;
|
||||||
}
|
}
|
||||||
@ -233,10 +231,7 @@ public class AetherGrapeEngine implements GrapeEngine {
|
|||||||
|
|
||||||
private List<Dependency> getManagedDependencies() {
|
private List<Dependency> getManagedDependencies() {
|
||||||
ArtifactDescriptorRequest parentRequest = new ArtifactDescriptorRequest();
|
ArtifactDescriptorRequest parentRequest = new ArtifactDescriptorRequest();
|
||||||
Artifact parentArtifact = new DefaultArtifact("org.springframework.boot",
|
parentRequest.setArtifact(this.parentArtifact);
|
||||||
"spring-boot-starter-parent", "pom",
|
|
||||||
this.artifactCoordinatesResolver.getVersion("spring-boot"));
|
|
||||||
parentRequest.setArtifact(parentArtifact);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ArtifactDescriptorResult artifactDescriptorResult = this.artifactDescriptorReader
|
ArtifactDescriptorResult artifactDescriptorResult = this.artifactDescriptorReader
|
||||||
@ -250,41 +245,33 @@ public class AetherGrapeEngine implements GrapeEngine {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Map<String, List<String>>> enumerateGrapes() {
|
public Map<String, Map<String, List<String>>> enumerateGrapes() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException("Grape enumeration is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URI[] resolve(Map args, Map... dependencies) {
|
public URI[] resolve(Map args, Map... dependencies) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException("Resolving to URIs is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URI[] resolve(Map args, List depsInfo, Map... dependencies) {
|
public URI[] resolve(Map args, List depsInfo, Map... dependencies) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException("Resolving to URIs is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map[] listDependencies(ClassLoader classLoader) {
|
public Map[] listDependencies(ClassLoader classLoader) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException("Listing dependencies is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addResolver(Map<String, Object> args) {
|
public void addResolver(Map<String, Object> args) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException("Adding a resolver is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object grab(String endorsedModule) {
|
public Object grab(String endorsedModule) {
|
||||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
throw new UnsupportedOperationException(
|
||||||
}
|
"Grabbing an endorsed module is not supported");
|
||||||
|
|
||||||
private static final class NopLoggerFactory implements LoggerFactory {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Logger getLogger(String name) {
|
|
||||||
// TODO Something more robust; I'm surprised this doesn't NPE
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class ProgressReporter {
|
private static final class ProgressReporter {
|
@ -0,0 +1,13 @@
|
|||||||
|
#Generated by Git-Commit-Id-Plugin
|
||||||
|
#Tue Oct 22 10:25:03 BST 2013
|
||||||
|
git.commit.id.abbrev=040321b
|
||||||
|
git.commit.user.email=awilkinson@gopivotal.com
|
||||||
|
git.commit.message.full=Isolate Aether in a separate class loader\n\nPrior to this commit, the Aether-based GrapeEngine was loaded in the\nsame class loader as the rest of Boot. This led to Aether's and its\ndependencies' types polluting the application's class path. Most\nnotably, this caused problems with logging as the logging framework\ncould be permaturely initialized.\n\nThis commit isolates AetherGrapeEngine, Aether and its dependencies\ninto a separate class loader. This is done by customizing the\npackaging of the CLI's jar file with the internal directory housing\nall of the types that will be loaded by the separate class loader.\n
|
||||||
|
git.commit.id=040321bf153db007290786623d45903cee27fa88
|
||||||
|
git.commit.message.short=Isolate Aether in a separate class loader
|
||||||
|
git.commit.user.name=Andy Wilkinson
|
||||||
|
git.build.user.name=Andy Wilkinson
|
||||||
|
git.build.user.email=awilkinson@gopivotal.com
|
||||||
|
git.branch=aether-grab
|
||||||
|
git.commit.time=2013-10-21T16\:24\:40+0100
|
||||||
|
git.build.time=2013-10-22T10\:25\:03+0100
|
@ -36,88 +36,26 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>commons-logging</groupId>
|
|
||||||
<artifactId>commons-logging</artifactId>
|
|
||||||
<version>1.1.3</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- Compile -->
|
<!-- Compile -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.sf.jopt-simple</groupId>
|
<groupId>net.sf.jopt-simple</groupId>
|
||||||
<artifactId>jopt-simple</artifactId>
|
<artifactId>jopt-simple</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.maven</groupId>
|
|
||||||
<artifactId>maven-aether-provider</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>org.eclipse.sisu.plexus</artifactId>
|
|
||||||
<groupId>org.eclipse.sisu</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.maven</groupId>
|
|
||||||
<artifactId>maven-settings-builder</artifactId>
|
|
||||||
<version>${maven.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.codehaus.groovy</groupId>
|
<groupId>org.codehaus.groovy</groupId>
|
||||||
<artifactId>groovy</artifactId>
|
<artifactId>groovy</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.aether</groupId>
|
|
||||||
<artifactId>aether-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.aether</groupId>
|
|
||||||
<artifactId>aether-connector-basic</artifactId>
|
|
||||||
<version>${aether.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.aether</groupId>
|
|
||||||
<artifactId>aether-impl</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.aether</groupId>
|
|
||||||
<artifactId>aether-spi</artifactId>
|
|
||||||
<version>${aether.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.aether</groupId>
|
|
||||||
<artifactId>aether-transport-file</artifactId>
|
|
||||||
<version>${aether.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.aether</groupId>
|
|
||||||
<artifactId>aether-transport-http</artifactId>
|
|
||||||
<version>${aether.version}</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>jcl-over-slf4j</artifactId>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.aether</groupId>
|
|
||||||
<artifactId>aether-util</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!-- Optional -->
|
<!-- Optional -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.codehaus.groovy</groupId>
|
<groupId>org.codehaus.groovy</groupId>
|
||||||
<artifactId>groovy-templates</artifactId>
|
<artifactId>groovy-templates</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- Provided -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>spring-boot-cli-grape</artifactId>
|
||||||
<scope>test</scope>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
|
||||||
<!-- Provided (to ensure in m2 repo for @grab to resolve) -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.integration</groupId>
|
|
||||||
<artifactId>spring-integration-dsl-groovy-core</artifactId>
|
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- Test -->
|
<!-- Test -->
|
||||||
@ -138,6 +76,11 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.javassist</groupId>
|
<groupId>org.javassist</groupId>
|
||||||
<artifactId>javassist</artifactId>
|
<artifactId>javassist</artifactId>
|
||||||
@ -202,7 +145,6 @@
|
|||||||
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
|
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
|
||||||
<transformer
|
<transformer
|
||||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
<mainClass>${start-class}</mainClass>
|
|
||||||
</transformer>
|
</transformer>
|
||||||
</transformers>
|
</transformers>
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
@ -215,8 +157,14 @@
|
|||||||
<inherited>false</inherited>
|
<inherited>false</inherited>
|
||||||
<configuration>
|
<configuration>
|
||||||
<descriptors>
|
<descriptors>
|
||||||
<descriptor>src/main/assembly/descriptor.xml</descriptor>
|
<descriptor>src/main/assembly/repackage-jar.xml</descriptor>
|
||||||
|
<descriptor>src/main/assembly/bin-package.xml</descriptor>
|
||||||
</descriptors>
|
</descriptors>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>${start-class}</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
@ -23,13 +23,11 @@
|
|||||||
<directoryMode>755</directoryMode>
|
<directoryMode>755</directoryMode>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
</fileSets>
|
</fileSets>
|
||||||
<dependencySets>
|
<files>
|
||||||
<dependencySet>
|
<file>
|
||||||
<includes>
|
<source>${project.build.directory}/${project.artifactId}-${project.version}-repackaged.jar</source>
|
||||||
<include>org.springframework.boot:spring-boot-cli:jar:*</include>
|
<outputDirectory>/lib</outputDirectory>
|
||||||
</includes>
|
<destName>${project.build.finalName}.jar</destName>
|
||||||
<outputDirectory>lib</outputDirectory>
|
</file>
|
||||||
<directoryMode>755</directoryMode>
|
</files>
|
||||||
</dependencySet>
|
|
||||||
</dependencySets>
|
|
||||||
</assembly>
|
</assembly>
|
25
spring-boot-cli/src/main/assembly/repackage-jar.xml
Normal file
25
spring-boot-cli/src/main/assembly/repackage-jar.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<assembly>
|
||||||
|
<id>repackaged</id>
|
||||||
|
<formats>
|
||||||
|
<format>jar</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<dependencySets>
|
||||||
|
<dependencySet>
|
||||||
|
<includes>
|
||||||
|
<include>org.springframework.boot:spring-boot-cli:jar:*</include>
|
||||||
|
</includes>
|
||||||
|
<unpack>true</unpack>
|
||||||
|
<directoryMode>755</directoryMode>
|
||||||
|
</dependencySet>
|
||||||
|
<dependencySet>
|
||||||
|
<includes>
|
||||||
|
<include>org.springframework.boot:spring-boot-cli-grape:jar:*</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory>internal</outputDirectory>
|
||||||
|
<directoryMode>755</directoryMode>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<unpack>true</unpack>
|
||||||
|
</dependencySet>
|
||||||
|
</dependencySets>
|
||||||
|
</assembly>
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012-2013 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.cli.command.tester;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract base class for tester implementations.
|
|
||||||
*
|
|
||||||
* @author Greg Turnquist
|
|
||||||
*/
|
|
||||||
public abstract class AbstractTester {
|
|
||||||
|
|
||||||
public TestResults findAndTest(List<Class<?>> compiled) throws FileNotFoundException {
|
|
||||||
Set<Class<?>> testable = findTestableClasses(compiled);
|
|
||||||
if (testable.size() == 0) {
|
|
||||||
return TestResults.NONE;
|
|
||||||
}
|
|
||||||
return test(testable.toArray(new Class<?>[] {}));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Set<Class<?>> findTestableClasses(List<Class<?>> compiled);
|
|
||||||
|
|
||||||
protected abstract TestResults test(Class<?>[] testable);
|
|
||||||
|
|
||||||
}
|
|
@ -16,13 +16,17 @@
|
|||||||
|
|
||||||
package org.springframework.boot.cli.compiler;
|
package org.springframework.boot.cli.compiler;
|
||||||
|
|
||||||
|
import groovy.grape.GrapeEngine;
|
||||||
import groovy.lang.Grab;
|
import groovy.lang.Grab;
|
||||||
import groovy.lang.GroovyClassLoader;
|
import groovy.lang.GroovyClassLoader;
|
||||||
import groovy.lang.GroovyClassLoader.ClassCollector;
|
import groovy.lang.GroovyClassLoader.ClassCollector;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -70,6 +74,9 @@ import org.codehaus.groovy.transform.ASTTransformationVisitor;
|
|||||||
*/
|
*/
|
||||||
public class GroovyCompiler {
|
public class GroovyCompiler {
|
||||||
|
|
||||||
|
private static final ClassLoader AETHER_CLASS_LOADER = new URLClassLoader(
|
||||||
|
new URL[] { GroovyCompiler.class.getResource("/internal/") });
|
||||||
|
|
||||||
private GroovyCompilerConfiguration configuration;
|
private GroovyCompilerConfiguration configuration;
|
||||||
|
|
||||||
private ExtendedGroovyClassLoader loader;
|
private ExtendedGroovyClassLoader loader;
|
||||||
@ -84,6 +91,7 @@ public class GroovyCompiler {
|
|||||||
* Create a new {@link GroovyCompiler} instance.
|
* Create a new {@link GroovyCompiler} instance.
|
||||||
* @param configuration the compiler configuration
|
* @param configuration the compiler configuration
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public GroovyCompiler(final GroovyCompilerConfiguration configuration) {
|
public GroovyCompiler(final GroovyCompilerConfiguration configuration) {
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
|
CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
|
||||||
@ -95,8 +103,20 @@ public class GroovyCompiler {
|
|||||||
this.artifactCoordinatesResolver = new PropertiesArtifactCoordinatesResolver(
|
this.artifactCoordinatesResolver = new PropertiesArtifactCoordinatesResolver(
|
||||||
this.loader);
|
this.loader);
|
||||||
|
|
||||||
new GrapeEngineInstaller(new AetherGrapeEngine(this.loader,
|
try {
|
||||||
this.artifactCoordinatesResolver)).install();
|
Class<GrapeEngine> grapeEngineClass = (Class<GrapeEngine>) AETHER_CLASS_LOADER
|
||||||
|
.loadClass("org.springframework.boot.cli.compiler.AetherGrapeEngine");
|
||||||
|
Constructor<GrapeEngine> constructor = grapeEngineClass.getConstructor(
|
||||||
|
GroovyClassLoader.class, String.class, String.class, String.class);
|
||||||
|
GrapeEngine grapeEngine = constructor.newInstance(this.loader,
|
||||||
|
"org.springframework.boot", "spring-boot-starter-parent",
|
||||||
|
this.artifactCoordinatesResolver.getVersion("spring-boot"));
|
||||||
|
|
||||||
|
new GrapeEngineInstaller(grapeEngine).install();
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new IllegalStateException("Failed to install custom GrapeEngine", ex);
|
||||||
|
}
|
||||||
|
|
||||||
compilerConfiguration
|
compilerConfiguration
|
||||||
.addCompilationCustomizers(new CompilerAutoConfigureCustomizer());
|
.addCompilationCustomizers(new CompilerAutoConfigureCustomizer());
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
#Generated by Git-Commit-Id-Plugin
|
||||||
|
#Tue Oct 22 10:25:04 BST 2013
|
||||||
|
git.commit.id.abbrev=040321b
|
||||||
|
git.commit.user.email=awilkinson@gopivotal.com
|
||||||
|
git.commit.message.full=Isolate Aether in a separate class loader\n\nPrior to this commit, the Aether-based GrapeEngine was loaded in the\nsame class loader as the rest of Boot. This led to Aether's and its\ndependencies' types polluting the application's class path. Most\nnotably, this caused problems with logging as the logging framework\ncould be permaturely initialized.\n\nThis commit isolates AetherGrapeEngine, Aether and its dependencies\ninto a separate class loader. This is done by customizing the\npackaging of the CLI's jar file with the internal directory housing\nall of the types that will be loaded by the separate class loader.\n
|
||||||
|
git.commit.id=040321bf153db007290786623d45903cee27fa88
|
||||||
|
git.commit.message.short=Isolate Aether in a separate class loader
|
||||||
|
git.commit.user.name=Andy Wilkinson
|
||||||
|
git.build.user.name=Andy Wilkinson
|
||||||
|
git.build.user.email=awilkinson@gopivotal.com
|
||||||
|
git.branch=aether-grab
|
||||||
|
git.commit.time=2013-10-21T16\:24\:40+0100
|
||||||
|
git.build.time=2013-10-22T10\:25\:04+0100
|
@ -16,6 +16,7 @@
|
|||||||
<module>../spring-boot-actuator</module>
|
<module>../spring-boot-actuator</module>
|
||||||
<module>../spring-boot-starters</module>
|
<module>../spring-boot-starters</module>
|
||||||
<module>../spring-boot-cli</module>
|
<module>../spring-boot-cli</module>
|
||||||
|
<module>../spring-boot-cli-grape</module>
|
||||||
<module>../spring-boot-samples</module>
|
<module>../spring-boot-samples</module>
|
||||||
<module>../spring-boot-integration-tests</module>
|
<module>../spring-boot-integration-tests</module>
|
||||||
<module>../spring-boot-javadoc</module>
|
<module>../spring-boot-javadoc</module>
|
||||||
|
@ -109,20 +109,40 @@
|
|||||||
<version>3.0.10</version>
|
<version>3.0.10</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.aether</groupId>
|
<groupId>org.eclipse.aether</groupId>
|
||||||
<artifactId>aether-api</artifactId>
|
<artifactId>aether-api</artifactId>
|
||||||
<version>${aether.version}</version>
|
<version>${aether.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.aether</groupId>
|
<groupId>org.eclipse.aether</groupId>
|
||||||
<artifactId>aether-impl</artifactId>
|
<artifactId>aether-connector-basic</artifactId>
|
||||||
<version>${aether.version}</version>
|
<version>${aether.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.aether</groupId>
|
<groupId>org.eclipse.aether</groupId>
|
||||||
<artifactId>aether-util</artifactId>
|
<artifactId>aether-impl</artifactId>
|
||||||
<version>${aether.version}</version>
|
<version>${aether.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.aether</groupId>
|
||||||
|
<artifactId>aether-spi</artifactId>
|
||||||
|
<version>${aether.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.aether</groupId>
|
||||||
|
<artifactId>aether-transport-file</artifactId>
|
||||||
|
<version>${aether.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.aether</groupId>
|
||||||
|
<artifactId>aether-transport-http</artifactId>
|
||||||
|
<version>${aether.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.aether</groupId>
|
||||||
|
<artifactId>aether-util</artifactId>
|
||||||
|
<version>${aether.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gradle</groupId>
|
<groupId>org.gradle</groupId>
|
||||||
<artifactId>gradle-core</artifactId>
|
<artifactId>gradle-core</artifactId>
|
||||||
|
@ -30,6 +30,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven</groupId>
|
<groupId>org.apache.maven</groupId>
|
||||||
<artifactId>maven-core</artifactId>
|
<artifactId>maven-core</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>asm</groupId>
|
||||||
|
<artifactId>asm</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven</groupId>
|
<groupId>org.apache.maven</groupId>
|
||||||
@ -72,12 +78,24 @@
|
|||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<artifactId>asm</artifactId>
|
|
||||||
<groupId>asm</groupId>
|
<groupId>asm</groupId>
|
||||||
|
<artifactId>asm</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<artifactId>asm-commons</artifactId>
|
|
||||||
<groupId>asm</groupId>
|
<groupId>asm</groupId>
|
||||||
|
<artifactId>asm-analysis</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>asm</groupId>
|
||||||
|
<artifactId>asm-commons</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>asm</groupId>
|
||||||
|
<artifactId>asm-tree</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>asm</groupId>
|
||||||
|
<artifactId>asm-util</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
Loading…
Reference in New Issue
Block a user