12 changed files with 0 additions and 1360 deletions
@ -1,125 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.springframework.boot.gradle.agent; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.net.URISyntaxException; |
|
||||||
import java.security.CodeSource; |
|
||||||
|
|
||||||
import org.gradle.api.Action; |
|
||||||
import org.gradle.api.Project; |
|
||||||
import org.gradle.api.Task; |
|
||||||
import org.gradle.api.tasks.JavaExec; |
|
||||||
import org.springframework.boot.gradle.SpringBootPluginExtension; |
|
||||||
|
|
||||||
/** |
|
||||||
* Add a java agent to the "run" task if configured. You can add an agent in 3 ways (4 if |
|
||||||
* you want to use native gradle features as well): |
|
||||||
* |
|
||||||
* <ol> |
|
||||||
* <li>Use "-Prun.agent=[path-to-jar]" on the gradle command line</li> |
|
||||||
* <li>Add an "agent" property (jar file) to the "springBoot" extension in build.gradle</li> |
|
||||||
* <li>As a special case springloaded is detected as a build script dependency</li> |
|
||||||
* </ol> |
|
||||||
* |
|
||||||
* @author Dave Syer |
|
||||||
* @author Phillip Webb |
|
||||||
*/ |
|
||||||
public class AgentTasksEnhancer implements Action<Project> { |
|
||||||
|
|
||||||
private static final String SPRING_LOADED_AGENT_CLASSNAME = "org.springsource.loaded.agent.SpringLoadedAgent"; |
|
||||||
|
|
||||||
private File agent; |
|
||||||
|
|
||||||
private Boolean noverify; |
|
||||||
|
|
||||||
@Override |
|
||||||
public void execute(Project project) { |
|
||||||
setup(project); |
|
||||||
if (this.agent != null) { |
|
||||||
for (Task task : project.getTasks()) { |
|
||||||
addAgent(project, task); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private void setup(Project project) { |
|
||||||
project.getLogger().info("Configuring agent"); |
|
||||||
SpringBootPluginExtension extension = project.getExtensions().getByType( |
|
||||||
SpringBootPluginExtension.class); |
|
||||||
this.noverify = extension.getNoverify(); |
|
||||||
this.agent = getAgent(project, extension); |
|
||||||
if (this.agent == null) { |
|
||||||
this.agent = getSpringLoadedAgent(); |
|
||||||
if (this.noverify == null) { |
|
||||||
this.noverify = true; |
|
||||||
} |
|
||||||
} |
|
||||||
project.getLogger().debug("Agent: " + this.agent); |
|
||||||
} |
|
||||||
|
|
||||||
private File getAgent(Project project, SpringBootPluginExtension extension) { |
|
||||||
if (project.hasProperty("run.agent")) { |
|
||||||
return project.file(project.property("run.agent")); |
|
||||||
} |
|
||||||
return extension.getAgent(); |
|
||||||
} |
|
||||||
|
|
||||||
private File getSpringLoadedAgent() { |
|
||||||
try { |
|
||||||
Class<?> loaded = Class.forName(SPRING_LOADED_AGENT_CLASSNAME); |
|
||||||
if (loaded != null) { |
|
||||||
CodeSource source = loaded.getProtectionDomain().getCodeSource(); |
|
||||||
if (source != null) { |
|
||||||
try { |
|
||||||
return new File(source.getLocation().toURI()); |
|
||||||
} |
|
||||||
catch (URISyntaxException ex) { |
|
||||||
return new File(source.getLocation().getPath()); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
catch (ClassNotFoundException ex) { |
|
||||||
// ignore;
|
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
private void addAgent(Project project, Task task) { |
|
||||||
if (task instanceof JavaExec) { |
|
||||||
addAgent(project, (JavaExec) task); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private void addAgent(Project project, JavaExec exec) { |
|
||||||
project.getLogger().debug("Attaching to: " + exec); |
|
||||||
if (this.agent != null) { |
|
||||||
project.getLogger().info("Attaching agent: " + this.agent); |
|
||||||
exec.jvmArgs("-javaagent:" + this.agent.getAbsolutePath()); |
|
||||||
if (this.noverify != null && this.noverify) { |
|
||||||
exec.jvmArgs("-noverify"); |
|
||||||
} |
|
||||||
Iterable<?> defaultJvmArgs = exec.getConventionMapping().getConventionValue( |
|
||||||
null, "jvmArgs", false); |
|
||||||
if (defaultJvmArgs != null) { |
|
||||||
exec.jvmArgs(defaultJvmArgs); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,115 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.springframework.boot.gradle.exclude; |
|
||||||
|
|
||||||
import org.gradle.api.Action; |
|
||||||
import org.gradle.api.Project; |
|
||||||
import org.gradle.api.artifacts.Configuration; |
|
||||||
import org.gradle.api.artifacts.Dependency; |
|
||||||
import org.gradle.api.artifacts.ModuleDependency; |
|
||||||
import org.gradle.api.artifacts.ResolvableDependencies; |
|
||||||
import org.gradle.api.internal.artifacts.DefaultExcludeRule; |
|
||||||
import org.gradle.api.logging.Logger; |
|
||||||
import org.springframework.boot.dependency.tools.Dependency.Exclusion; |
|
||||||
import org.springframework.boot.dependency.tools.ManagedDependencies; |
|
||||||
import org.springframework.boot.gradle.VersionManagedDependencies; |
|
||||||
|
|
||||||
/** |
|
||||||
* {@link Action} to apply exclude rules. |
|
||||||
* |
|
||||||
* @author Phillip Webb |
|
||||||
*/ |
|
||||||
public class ApplyExcludeRules implements Action<Configuration> { |
|
||||||
|
|
||||||
private final Logger logger; |
|
||||||
|
|
||||||
private final VersionManagedDependencies versionManagedDependencies; |
|
||||||
|
|
||||||
public ApplyExcludeRules(Project project) { |
|
||||||
this.logger = project.getLogger(); |
|
||||||
this.versionManagedDependencies = new VersionManagedDependencies(project); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void execute(Configuration configuration) { |
|
||||||
if (!VersionManagedDependencies.CONFIGURATION.equals(configuration.getName())) { |
|
||||||
configuration.getIncoming().beforeResolve( |
|
||||||
new Action<ResolvableDependencies>() { |
|
||||||
@Override |
|
||||||
public void execute(ResolvableDependencies resolvableDependencies) { |
|
||||||
resolvableDependencies.getDependencies().all( |
|
||||||
new Action<Dependency>() { |
|
||||||
@Override |
|
||||||
public void execute(Dependency dependency) { |
|
||||||
applyExcludeRules(dependency); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private void applyExcludeRules(Dependency dependency) { |
|
||||||
if (dependency instanceof ModuleDependency) { |
|
||||||
applyExcludeRules((ModuleDependency) dependency); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private void applyExcludeRules(ModuleDependency dependency) { |
|
||||||
ManagedDependencies managedDependencies = versionManagedDependencies |
|
||||||
.getManagedDependencies(); |
|
||||||
// flat directory repositories do not have groups
|
|
||||||
if (dependency.getGroup() != null) { |
|
||||||
org.springframework.boot.dependency.tools.Dependency managedDependency = managedDependencies |
|
||||||
.find(dependency.getGroup(), dependency.getName()); |
|
||||||
if (managedDependency != null) { |
|
||||||
for (Exclusion exclusion : managedDependency.getExclusions()) { |
|
||||||
addExcludeRule(dependency, exclusion); |
|
||||||
} |
|
||||||
addImplicitExcludeRules(dependency); |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
logger.debug("No exclusions rules applied for non-managed dependency " |
|
||||||
+ dependency); |
|
||||||
} |
|
||||||
|
|
||||||
private void addExcludeRule(ModuleDependency dependency, Exclusion exclusion) { |
|
||||||
logger.info("Adding managed exclusion rule " + exclusion + " to " + dependency); |
|
||||||
DefaultExcludeRule rule = new DefaultExcludeRule(exclusion.getGroupId(), |
|
||||||
exclusion.getArtifactId()); |
|
||||||
dependency.getExcludeRules().add(rule); |
|
||||||
} |
|
||||||
|
|
||||||
private void addImplicitExcludeRules(ModuleDependency dependency) { |
|
||||||
if (isStarter(dependency)) { |
|
||||||
logger.info("Adding implicit managed exclusion rules to starter " |
|
||||||
+ dependency); |
|
||||||
dependency.getExcludeRules().add( |
|
||||||
new DefaultExcludeRule("commons-logging", "commons-logging")); |
|
||||||
dependency.getExcludeRules().add( |
|
||||||
new DefaultExcludeRule("commons-logging", "commons-logging-api")); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private boolean isStarter(ModuleDependency dependency) { |
|
||||||
return (dependency.getGroup() != null |
|
||||||
&& dependency.getGroup().equals("org.springframework.boot") && dependency |
|
||||||
.getName().startsWith("spring-boot-starter")); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,39 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.springframework.boot.gradle.exclude; |
|
||||||
|
|
||||||
import org.gradle.api.Project; |
|
||||||
import org.springframework.boot.gradle.PluginFeatures; |
|
||||||
import org.springframework.boot.gradle.SpringBootPluginExtension; |
|
||||||
|
|
||||||
/** |
|
||||||
* {@link PluginFeatures} to apply exclusion rules. |
|
||||||
* |
|
||||||
* @author Phillip Webb |
|
||||||
*/ |
|
||||||
public class ExcludePluginFeatures implements PluginFeatures { |
|
||||||
|
|
||||||
@Override |
|
||||||
public void apply(Project project) { |
|
||||||
SpringBootPluginExtension extension = project.getExtensions().getByType( |
|
||||||
SpringBootPluginExtension.class); |
|
||||||
if (extension.isApplyExcludeRules()) { |
|
||||||
project.getConfigurations().all(new ApplyExcludeRules(project)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,242 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.springframework.boot.gradle.repackage; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.io.IOException; |
|
||||||
import java.util.HashSet; |
|
||||||
import java.util.LinkedHashSet; |
|
||||||
import java.util.Set; |
|
||||||
|
|
||||||
import org.gradle.api.Project; |
|
||||||
import org.gradle.api.artifacts.Configuration; |
|
||||||
import org.gradle.api.artifacts.Dependency; |
|
||||||
import org.gradle.api.artifacts.FileCollectionDependency; |
|
||||||
import org.gradle.api.artifacts.ModuleVersionIdentifier; |
|
||||||
import org.gradle.api.artifacts.ProjectDependency; |
|
||||||
import org.gradle.api.artifacts.ResolvedArtifact; |
|
||||||
import org.springframework.boot.gradle.SpringBootPluginExtension; |
|
||||||
import org.springframework.boot.loader.tools.Libraries; |
|
||||||
import org.springframework.boot.loader.tools.Library; |
|
||||||
import org.springframework.boot.loader.tools.LibraryCallback; |
|
||||||
import org.springframework.boot.loader.tools.LibraryScope; |
|
||||||
|
|
||||||
/** |
|
||||||
* Expose Gradle {@link Configuration}s as {@link Libraries}. |
|
||||||
* |
|
||||||
* @author Phillip Webb |
|
||||||
* @author Andy Wilkinson |
|
||||||
*/ |
|
||||||
class ProjectLibraries implements Libraries { |
|
||||||
|
|
||||||
private final Project project; |
|
||||||
|
|
||||||
private final SpringBootPluginExtension extension; |
|
||||||
|
|
||||||
private String providedConfigurationName = "providedRuntime"; |
|
||||||
|
|
||||||
private String customConfigurationName = null; |
|
||||||
|
|
||||||
/** |
|
||||||
* Create a new {@link ProjectLibraries} instance of the specified {@link Project}. |
|
||||||
* @param project the gradle project |
|
||||||
* @param extension the extension |
|
||||||
*/ |
|
||||||
public ProjectLibraries(Project project, SpringBootPluginExtension extension) { |
|
||||||
this.project = project; |
|
||||||
this.extension = extension; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Set the name of the provided configuration. Defaults to 'providedRuntime'. |
|
||||||
* @param providedConfigurationName the providedConfigurationName to set |
|
||||||
*/ |
|
||||||
public void setProvidedConfigurationName(String providedConfigurationName) { |
|
||||||
this.providedConfigurationName = providedConfigurationName; |
|
||||||
} |
|
||||||
|
|
||||||
public void setCustomConfigurationName(String customConfigurationName) { |
|
||||||
this.customConfigurationName = customConfigurationName; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void doWithLibraries(LibraryCallback callback) throws IOException { |
|
||||||
Set<GradleLibrary> custom = getLibraries(this.customConfigurationName, |
|
||||||
LibraryScope.CUSTOM); |
|
||||||
if (custom != null) { |
|
||||||
libraries(custom, callback); |
|
||||||
} |
|
||||||
else { |
|
||||||
Set<GradleLibrary> compile = getLibraries("compile", LibraryScope.COMPILE); |
|
||||||
Set<GradleLibrary> runtime = getLibraries("runtime", LibraryScope.RUNTIME); |
|
||||||
runtime = minus(runtime, compile); |
|
||||||
Set<GradleLibrary> provided = getLibraries(this.providedConfigurationName, |
|
||||||
LibraryScope.PROVIDED); |
|
||||||
if (provided != null) { |
|
||||||
compile = minus(compile, provided); |
|
||||||
runtime = minus(runtime, provided); |
|
||||||
} |
|
||||||
libraries(compile, callback); |
|
||||||
libraries(runtime, callback); |
|
||||||
libraries(provided, callback); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private Set<GradleLibrary> getLibraries(String configurationName, LibraryScope scope) { |
|
||||||
Configuration configuration = (configurationName == null ? null : this.project |
|
||||||
.getConfigurations().findByName(configurationName)); |
|
||||||
if (configuration == null) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
Set<GradleLibrary> libraries = new LinkedHashSet<GradleLibrary>(); |
|
||||||
for (ResolvedArtifact artifact : configuration.getResolvedConfiguration() |
|
||||||
.getResolvedArtifacts()) { |
|
||||||
libraries.add(new ResolvedArtifactLibrary(artifact, scope)); |
|
||||||
} |
|
||||||
libraries.addAll(getLibrariesForFileDependencies(configuration, scope)); |
|
||||||
return libraries; |
|
||||||
} |
|
||||||
|
|
||||||
private Set<GradleLibrary> getLibrariesForFileDependencies( |
|
||||||
Configuration configuration, LibraryScope scope) { |
|
||||||
Set<GradleLibrary> libraries = new LinkedHashSet<GradleLibrary>(); |
|
||||||
for (Dependency dependency : configuration.getIncoming().getDependencies()) { |
|
||||||
if (dependency instanceof FileCollectionDependency) { |
|
||||||
FileCollectionDependency fileDependency = (FileCollectionDependency) dependency; |
|
||||||
for (File file : fileDependency.resolve()) { |
|
||||||
libraries.add(new GradleLibrary(fileDependency.getGroup(), file, |
|
||||||
scope)); |
|
||||||
} |
|
||||||
} |
|
||||||
else if (dependency instanceof ProjectDependency) { |
|
||||||
ProjectDependency projectDependency = (ProjectDependency) dependency; |
|
||||||
libraries.addAll(getLibrariesForFileDependencies( |
|
||||||
projectDependency.getProjectConfiguration(), scope)); |
|
||||||
} |
|
||||||
} |
|
||||||
return libraries; |
|
||||||
} |
|
||||||
|
|
||||||
private Set<GradleLibrary> minus(Set<GradleLibrary> source, |
|
||||||
Set<GradleLibrary> toRemove) { |
|
||||||
if (source == null || toRemove == null) { |
|
||||||
return source; |
|
||||||
} |
|
||||||
Set<File> filesToRemove = new HashSet<File>(); |
|
||||||
for (GradleLibrary library : toRemove) { |
|
||||||
filesToRemove.add(library.getFile()); |
|
||||||
} |
|
||||||
Set<GradleLibrary> result = new LinkedHashSet<GradleLibrary>(); |
|
||||||
for (GradleLibrary library : source) { |
|
||||||
if (!filesToRemove.contains(library.getFile())) { |
|
||||||
result.add(library); |
|
||||||
} |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
private void libraries(Set<GradleLibrary> libraries, LibraryCallback callback) |
|
||||||
throws IOException { |
|
||||||
if (libraries != null) { |
|
||||||
Set<String> duplicates = getDuplicates(libraries); |
|
||||||
for (GradleLibrary library : libraries) { |
|
||||||
library.setIncludeGroupName(duplicates.contains(library.getName())); |
|
||||||
callback.library(library); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private Set<String> getDuplicates(Set<GradleLibrary> libraries) { |
|
||||||
Set<String> duplicates = new HashSet<String>(); |
|
||||||
Set<String> seen = new HashSet<String>(); |
|
||||||
for (GradleLibrary library : libraries) { |
|
||||||
if (library.getFile() != null && !seen.add(library.getFile().getName())) { |
|
||||||
duplicates.add(library.getFile().getName()); |
|
||||||
} |
|
||||||
} |
|
||||||
return duplicates; |
|
||||||
} |
|
||||||
|
|
||||||
private class GradleLibrary extends Library { |
|
||||||
|
|
||||||
private final String group; |
|
||||||
|
|
||||||
private boolean includeGroupName; |
|
||||||
|
|
||||||
public GradleLibrary(String group, File file, LibraryScope scope) { |
|
||||||
super(file, scope); |
|
||||||
this.group = group; |
|
||||||
} |
|
||||||
|
|
||||||
public void setIncludeGroupName(boolean includeGroupName) { |
|
||||||
this.includeGroupName = includeGroupName; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getName() { |
|
||||||
String name = super.getName(); |
|
||||||
if (this.includeGroupName && this.group != null) { |
|
||||||
name = this.group + "-" + name; |
|
||||||
} |
|
||||||
return name; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int hashCode() { |
|
||||||
return getFile().hashCode(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean equals(Object obj) { |
|
||||||
if (obj instanceof GradleLibrary) { |
|
||||||
return getFile().equals(((GradleLibrary) obj).getFile()); |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String toString() { |
|
||||||
return getFile().getAbsolutePath(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Adapts a {@link ResolvedArtifact} to a {@link Library}. |
|
||||||
*/ |
|
||||||
private class ResolvedArtifactLibrary extends GradleLibrary { |
|
||||||
|
|
||||||
private final ResolvedArtifact artifact; |
|
||||||
|
|
||||||
public ResolvedArtifactLibrary(ResolvedArtifact artifact, LibraryScope scope) { |
|
||||||
super(artifact.getModuleVersion().getId().getGroup(), artifact.getFile(), |
|
||||||
scope); |
|
||||||
this.artifact = artifact; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isUnpackRequired() { |
|
||||||
if (ProjectLibraries.this.extension.getRequiresUnpack() != null) { |
|
||||||
ModuleVersionIdentifier id = this.artifact.getModuleVersion().getId(); |
|
||||||
return ProjectLibraries.this.extension.getRequiresUnpack().contains( |
|
||||||
id.getGroup() + ":" + id.getName()); |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,161 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.gradle.repackage; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
import org.gradle.api.Action; |
|
||||||
import org.gradle.api.Project; |
|
||||||
import org.gradle.api.Task; |
|
||||||
import org.gradle.api.artifacts.Configuration; |
|
||||||
import org.gradle.api.artifacts.Dependency; |
|
||||||
import org.gradle.api.logging.Logger; |
|
||||||
import org.gradle.api.plugins.BasePlugin; |
|
||||||
import org.gradle.api.plugins.JavaPlugin; |
|
||||||
import org.gradle.api.tasks.TaskDependency; |
|
||||||
import org.gradle.api.tasks.bundling.Jar; |
|
||||||
import org.springframework.boot.gradle.PluginFeatures; |
|
||||||
import org.springframework.boot.gradle.SpringBootPluginExtension; |
|
||||||
import org.springframework.boot.loader.tools.Library; |
|
||||||
import org.springframework.boot.loader.tools.LibraryCallback; |
|
||||||
import org.springframework.util.StringUtils; |
|
||||||
|
|
||||||
/** |
|
||||||
* {@link PluginFeatures} to add repackage support. |
|
||||||
* |
|
||||||
* @author Phillip Webb |
|
||||||
* @author Dave Syer |
|
||||||
* @author Andy Wilkinson |
|
||||||
*/ |
|
||||||
public class RepackagePluginFeatures implements PluginFeatures { |
|
||||||
|
|
||||||
public static final String REPACKAGE_TASK_NAME = "bootRepackage"; |
|
||||||
|
|
||||||
@Override |
|
||||||
public void apply(Project project) { |
|
||||||
addRepackageTask(project); |
|
||||||
registerRepackageTaskProperty(project); |
|
||||||
} |
|
||||||
|
|
||||||
private void addRepackageTask(Project project) { |
|
||||||
RepackageTask task = project.getTasks().create(REPACKAGE_TASK_NAME, |
|
||||||
RepackageTask.class); |
|
||||||
task.setDescription("Repackage existing JAR and WAR " |
|
||||||
+ "archives so that they can be executed from the command " |
|
||||||
+ "line using 'java -jar'"); |
|
||||||
task.setGroup(BasePlugin.BUILD_GROUP); |
|
||||||
Configuration runtimeConfiguration = project.getConfigurations().getByName( |
|
||||||
JavaPlugin.RUNTIME_CONFIGURATION_NAME); |
|
||||||
TaskDependency runtimeProjectDependencyJarTasks = runtimeConfiguration |
|
||||||
.getTaskDependencyFromProjectDependency(true, JavaPlugin.JAR_TASK_NAME); |
|
||||||
task.dependsOn( |
|
||||||
project.getConfigurations().getByName(Dependency.ARCHIVES_CONFIGURATION) |
|
||||||
.getAllArtifacts().getBuildDependencies(), |
|
||||||
runtimeProjectDependencyJarTasks); |
|
||||||
registerOutput(project, task); |
|
||||||
ensureTaskRunsOnAssembly(project, task); |
|
||||||
} |
|
||||||
|
|
||||||
private void registerOutput(Project project, final RepackageTask task) { |
|
||||||
project.afterEvaluate(new Action<Project>() { |
|
||||||
@Override |
|
||||||
public void execute(Project project) { |
|
||||||
project.getTasks().withType(Jar.class, |
|
||||||
new RegisterInputsOutputsAction(task)); |
|
||||||
Object withJar = task.getWithJarTask(); |
|
||||||
if (withJar != null) { |
|
||||||
task.dependsOn(withJar); |
|
||||||
} |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
private void ensureTaskRunsOnAssembly(Project project, Task task) { |
|
||||||
project.getTasks().getByName(BasePlugin.ASSEMBLE_TASK_NAME).dependsOn(task); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Register BootRepackage so that we can use task {@code foo(type: BootRepackage)}. |
|
||||||
*/ |
|
||||||
private void registerRepackageTaskProperty(Project project) { |
|
||||||
project.getExtensions().getExtraProperties() |
|
||||||
.set("BootRepackage", RepackageTask.class); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Register task input/outputs when classifiers are used |
|
||||||
*/ |
|
||||||
private static class RegisterInputsOutputsAction implements Action<Jar> { |
|
||||||
|
|
||||||
private final RepackageTask task; |
|
||||||
|
|
||||||
private final Project project; |
|
||||||
|
|
||||||
public RegisterInputsOutputsAction(RepackageTask task) { |
|
||||||
this.task = task; |
|
||||||
this.project = task.getProject(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void execute(Jar jarTask) { |
|
||||||
if ("".equals(jarTask.getClassifier())) { |
|
||||||
String classifier = this.task.getClassifier(); |
|
||||||
if (classifier == null) { |
|
||||||
SpringBootPluginExtension extension = this.project.getExtensions() |
|
||||||
.getByType(SpringBootPluginExtension.class); |
|
||||||
classifier = extension.getClassifier(); |
|
||||||
this.task.setClassifier(classifier); |
|
||||||
} |
|
||||||
if (classifier != null) { |
|
||||||
setupInputOutputs(jarTask, classifier); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private void setupInputOutputs(Jar jarTask, String classifier) { |
|
||||||
Logger logger = this.project.getLogger(); |
|
||||||
logger.debug("Using classifier: " + classifier + " for task " |
|
||||||
+ this.task.getName()); |
|
||||||
File inputFile = jarTask.getArchivePath(); |
|
||||||
String outputName = inputFile.getName(); |
|
||||||
outputName = StringUtils.stripFilenameExtension(outputName) + "-" |
|
||||||
+ classifier + "." + StringUtils.getFilenameExtension(outputName); |
|
||||||
File outputFile = new File(inputFile.getParentFile(), outputName); |
|
||||||
this.task.getInputs().file(jarTask); |
|
||||||
addLibraryDependencies(this.task); |
|
||||||
this.task.getOutputs().file(outputFile); |
|
||||||
this.task.setOutputFile(outputFile); |
|
||||||
} |
|
||||||
|
|
||||||
private void addLibraryDependencies(final RepackageTask task) { |
|
||||||
try { |
|
||||||
task.getLibraries().doWithLibraries(new LibraryCallback() { |
|
||||||
@Override |
|
||||||
public void library(Library library) throws IOException { |
|
||||||
task.getInputs().file(library.getFile()); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
catch (IOException ex) { |
|
||||||
throw new IllegalStateException(ex); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,237 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.springframework.boot.gradle.repackage; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.io.IOException; |
|
||||||
import java.util.HashSet; |
|
||||||
import java.util.Set; |
|
||||||
import java.util.concurrent.TimeUnit; |
|
||||||
|
|
||||||
import org.gradle.api.Action; |
|
||||||
import org.gradle.api.DefaultTask; |
|
||||||
import org.gradle.api.Project; |
|
||||||
import org.gradle.api.tasks.TaskAction; |
|
||||||
import org.gradle.api.tasks.bundling.Jar; |
|
||||||
import org.springframework.boot.gradle.SpringBootPluginExtension; |
|
||||||
import org.springframework.boot.loader.tools.Repackager; |
|
||||||
import org.springframework.util.FileCopyUtils; |
|
||||||
|
|
||||||
/** |
|
||||||
* Repackage task. |
|
||||||
* |
|
||||||
* @author Phillip Webb |
|
||||||
* @author Janne Valkealahti |
|
||||||
* @author Andy Wilkinson |
|
||||||
*/ |
|
||||||
public class RepackageTask extends DefaultTask { |
|
||||||
|
|
||||||
private static final long FIND_WARNING_TIMEOUT = TimeUnit.SECONDS.toMillis(10); |
|
||||||
|
|
||||||
private String customConfiguration; |
|
||||||
|
|
||||||
private Object withJarTask; |
|
||||||
|
|
||||||
private String mainClass; |
|
||||||
|
|
||||||
private String classifier; |
|
||||||
|
|
||||||
private File outputFile; |
|
||||||
|
|
||||||
public void setCustomConfiguration(String customConfiguration) { |
|
||||||
this.customConfiguration = customConfiguration; |
|
||||||
} |
|
||||||
|
|
||||||
public Object getWithJarTask() { |
|
||||||
return this.withJarTask; |
|
||||||
} |
|
||||||
|
|
||||||
public void setWithJarTask(Object withJarTask) { |
|
||||||
this.withJarTask = withJarTask; |
|
||||||
} |
|
||||||
|
|
||||||
public void setMainClass(String mainClass) { |
|
||||||
this.mainClass = mainClass; |
|
||||||
} |
|
||||||
|
|
||||||
public String getMainClass() { |
|
||||||
return this.mainClass; |
|
||||||
} |
|
||||||
|
|
||||||
public String getClassifier() { |
|
||||||
return this.classifier; |
|
||||||
} |
|
||||||
|
|
||||||
public void setClassifier(String classifier) { |
|
||||||
this.classifier = classifier; |
|
||||||
} |
|
||||||
|
|
||||||
@TaskAction |
|
||||||
public void repackage() { |
|
||||||
Project project = getProject(); |
|
||||||
SpringBootPluginExtension extension = project.getExtensions().getByType( |
|
||||||
SpringBootPluginExtension.class); |
|
||||||
ProjectLibraries libraries = getLibraries(); |
|
||||||
project.getTasks().withType(Jar.class, new RepackageAction(extension, libraries)); |
|
||||||
} |
|
||||||
|
|
||||||
public ProjectLibraries getLibraries() { |
|
||||||
Project project = getProject(); |
|
||||||
SpringBootPluginExtension extension = project.getExtensions().getByType( |
|
||||||
SpringBootPluginExtension.class); |
|
||||||
ProjectLibraries libraries = new ProjectLibraries(project, extension); |
|
||||||
if (extension.getProvidedConfiguration() != null) { |
|
||||||
libraries.setProvidedConfigurationName(extension.getProvidedConfiguration()); |
|
||||||
} |
|
||||||
if (this.customConfiguration != null) { |
|
||||||
libraries.setCustomConfigurationName(this.customConfiguration); |
|
||||||
} |
|
||||||
else if (extension.getCustomConfiguration() != null) { |
|
||||||
libraries.setCustomConfigurationName(extension.getCustomConfiguration()); |
|
||||||
} |
|
||||||
return libraries; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Action to repackage JARs. |
|
||||||
*/ |
|
||||||
private class RepackageAction implements Action<Jar> { |
|
||||||
|
|
||||||
private final SpringBootPluginExtension extension; |
|
||||||
|
|
||||||
private final ProjectLibraries libraries; |
|
||||||
|
|
||||||
public RepackageAction(SpringBootPluginExtension extension, |
|
||||||
ProjectLibraries libraries) { |
|
||||||
this.extension = extension; |
|
||||||
this.libraries = libraries; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void execute(Jar jarTask) { |
|
||||||
if (!RepackageTask.this.isEnabled()) { |
|
||||||
getLogger().info("Repackage disabled"); |
|
||||||
return; |
|
||||||
} |
|
||||||
Object withJarTask = RepackageTask.this.withJarTask; |
|
||||||
if (!isTaskMatch(jarTask, withJarTask)) { |
|
||||||
getLogger().info( |
|
||||||
"Jar task not repackaged (didn't match withJarTask): " + jarTask); |
|
||||||
return; |
|
||||||
} |
|
||||||
File file = jarTask.getArchivePath(); |
|
||||||
if (file.exists()) { |
|
||||||
repackage(file); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private boolean isTaskMatch(Jar task, Object withJarTask) { |
|
||||||
if (withJarTask == null) { |
|
||||||
if ("".equals(task.getClassifier())) { |
|
||||||
Set<Object> tasksWithCustomRepackaging = new HashSet<Object>(); |
|
||||||
for (RepackageTask repackageTask : RepackageTask.this.getProject() |
|
||||||
.getTasks().withType(RepackageTask.class)) { |
|
||||||
if (repackageTask.getWithJarTask() != null) { |
|
||||||
tasksWithCustomRepackaging |
|
||||||
.add(repackageTask.getWithJarTask()); |
|
||||||
} |
|
||||||
} |
|
||||||
return !tasksWithCustomRepackaging.contains(task); |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
return task.equals(withJarTask) || task.getName().equals(withJarTask); |
|
||||||
} |
|
||||||
|
|
||||||
private void repackage(File file) { |
|
||||||
File outputFile = RepackageTask.this.outputFile; |
|
||||||
if (outputFile != null && !file.equals(outputFile)) { |
|
||||||
copy(file, outputFile); |
|
||||||
file = outputFile; |
|
||||||
} |
|
||||||
Repackager repackager = new LoggingRepackager(file); |
|
||||||
setMainClass(repackager); |
|
||||||
if (this.extension.convertLayout() != null) { |
|
||||||
repackager.setLayout(this.extension.convertLayout()); |
|
||||||
} |
|
||||||
repackager.setBackupSource(this.extension.isBackupSource()); |
|
||||||
try { |
|
||||||
repackager.repackage(file, this.libraries); |
|
||||||
} |
|
||||||
catch (IOException ex) { |
|
||||||
throw new IllegalStateException(ex.getMessage(), ex); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private void copy(File source, File dest) { |
|
||||||
try { |
|
||||||
FileCopyUtils.copy(source, dest); |
|
||||||
} |
|
||||||
catch (IOException ex) { |
|
||||||
throw new IllegalStateException(ex.getMessage(), ex); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private void setMainClass(Repackager repackager) { |
|
||||||
String mainClass = (String) getProject().property("mainClassName"); |
|
||||||
if (RepackageTask.this.mainClass != null) { |
|
||||||
mainClass = RepackageTask.this.mainClass; |
|
||||||
} |
|
||||||
else if (this.extension.getMainClass() != null) { |
|
||||||
mainClass = this.extension.getMainClass(); |
|
||||||
} |
|
||||||
else if (getProject().getTasks().getByName("run").hasProperty("main")) { |
|
||||||
mainClass = (String) getProject().getTasks().getByName("run") |
|
||||||
.property("main"); |
|
||||||
} |
|
||||||
getLogger().info("Setting mainClass: " + mainClass); |
|
||||||
repackager.setMainClass(mainClass); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* {@link Repackager} that also logs when searching takes too long. |
|
||||||
*/ |
|
||||||
private class LoggingRepackager extends Repackager { |
|
||||||
|
|
||||||
public LoggingRepackager(File source) { |
|
||||||
super(source); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected String findMainMethod(java.util.jar.JarFile source) throws IOException { |
|
||||||
long startTime = System.currentTimeMillis(); |
|
||||||
try { |
|
||||||
return super.findMainMethod(source); |
|
||||||
} |
|
||||||
finally { |
|
||||||
long duration = System.currentTimeMillis() - startTime; |
|
||||||
if (duration > FIND_WARNING_TIMEOUT) { |
|
||||||
getLogger().warn( |
|
||||||
"Searching for the main-class is taking " |
|
||||||
+ "some time, consider using setting " |
|
||||||
+ "'springBoot.mainClass'"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void setOutputFile(File file) { |
|
||||||
this.outputFile = file; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,41 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.springframework.boot.gradle.resolve; |
|
||||||
|
|
||||||
import org.gradle.api.Action; |
|
||||||
import org.gradle.api.Project; |
|
||||||
import org.gradle.api.artifacts.Configuration; |
|
||||||
import org.springframework.boot.gradle.PluginFeatures; |
|
||||||
|
|
||||||
/** |
|
||||||
* {@link PluginFeatures} to add version resolution support. |
|
||||||
* |
|
||||||
* @author Phillip Webb |
|
||||||
*/ |
|
||||||
public class ResolvePluginFeatures implements PluginFeatures { |
|
||||||
|
|
||||||
@Override |
|
||||||
public void apply(final Project project) { |
|
||||||
project.getConfigurations().all(new Action<Configuration>() { |
|
||||||
@Override |
|
||||||
public void execute(Configuration configuration) { |
|
||||||
SpringBootResolutionStrategy.applyToConfiguration(project, configuration); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,79 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.springframework.boot.gradle.resolve; |
|
||||||
|
|
||||||
import org.gradle.api.Action; |
|
||||||
import org.gradle.api.Project; |
|
||||||
import org.gradle.api.artifacts.Configuration; |
|
||||||
import org.gradle.api.artifacts.DependencyResolveDetails; |
|
||||||
import org.gradle.api.artifacts.ModuleVersionSelector; |
|
||||||
import org.springframework.boot.dependency.tools.Dependency; |
|
||||||
import org.springframework.boot.dependency.tools.ManagedDependencies; |
|
||||||
import org.springframework.boot.gradle.VersionManagedDependencies; |
|
||||||
|
|
||||||
/** |
|
||||||
* A resolution strategy to resolve missing version numbers using the |
|
||||||
* 'spring-boot-dependencies' POM. |
|
||||||
* |
|
||||||
* @author Phillip Webb |
|
||||||
*/ |
|
||||||
public class SpringBootResolutionStrategy { |
|
||||||
|
|
||||||
private static final String SPRING_BOOT_GROUP = "org.springframework.boot"; |
|
||||||
|
|
||||||
public static void applyToConfiguration(final Project project, |
|
||||||
Configuration configuration) { |
|
||||||
if (VersionManagedDependencies.CONFIGURATION.equals(configuration.getName())) { |
|
||||||
return; |
|
||||||
} |
|
||||||
VersionResolver versionResolver = new VersionResolver(project); |
|
||||||
configuration.getResolutionStrategy().eachDependency(versionResolver); |
|
||||||
} |
|
||||||
|
|
||||||
private static class VersionResolver implements Action<DependencyResolveDetails> { |
|
||||||
|
|
||||||
private final VersionManagedDependencies versionManagedDependencies; |
|
||||||
|
|
||||||
public VersionResolver(Project project) { |
|
||||||
this.versionManagedDependencies = new VersionManagedDependencies(project); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void execute(DependencyResolveDetails resolveDetails) { |
|
||||||
String version = resolveDetails.getTarget().getVersion(); |
|
||||||
if (version == null || version.trim().length() == 0) { |
|
||||||
resolve(resolveDetails); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private void resolve(DependencyResolveDetails resolveDetails) { |
|
||||||
ManagedDependencies dependencies = this.versionManagedDependencies |
|
||||||
.getManagedDependencies(); |
|
||||||
ModuleVersionSelector target = resolveDetails.getTarget(); |
|
||||||
if (SPRING_BOOT_GROUP.equals(target.getGroup())) { |
|
||||||
resolveDetails.useVersion(dependencies.getSpringBootVersion()); |
|
||||||
return; |
|
||||||
} |
|
||||||
Dependency dependency = dependencies |
|
||||||
.find(target.getGroup(), target.getName()); |
|
||||||
if (dependency != null) { |
|
||||||
resolveDetails.useVersion(dependency.getVersion()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,82 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.gradle.run; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.LinkedHashSet; |
|
||||||
import java.util.List; |
|
||||||
import java.util.Set; |
|
||||||
|
|
||||||
import org.gradle.api.internal.file.collections.SimpleFileCollection; |
|
||||||
import org.gradle.api.tasks.JavaExec; |
|
||||||
import org.gradle.api.tasks.SourceSet; |
|
||||||
import org.springframework.boot.loader.tools.FileUtils; |
|
||||||
|
|
||||||
/** |
|
||||||
* Extension of the standard 'run' task with additional Spring Boot features. |
|
||||||
* |
|
||||||
* @author Dave Syer |
|
||||||
* @author Phillip Webb |
|
||||||
*/ |
|
||||||
public class BootRunTask extends JavaExec { |
|
||||||
|
|
||||||
/** |
|
||||||
* Whether or not resources (typically in {@code src/main/resources} are added |
|
||||||
* directly to the classpath. When enabled (the default), this allows live in-place |
|
||||||
* editing of resources. Duplicate resources are removed from the resource output |
|
||||||
* directory to prevent them from appearing twice if |
|
||||||
* {@code ClassLoader.getResources()} is called. |
|
||||||
*/ |
|
||||||
private boolean addResources = true; |
|
||||||
|
|
||||||
public boolean getAddResources() { |
|
||||||
return this.addResources; |
|
||||||
} |
|
||||||
|
|
||||||
public void setAddResources(boolean addResources) { |
|
||||||
this.addResources = addResources; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void exec() { |
|
||||||
addResourcesIfNecessary(); |
|
||||||
super.exec(); |
|
||||||
} |
|
||||||
|
|
||||||
private void addResourcesIfNecessary() { |
|
||||||
if (this.addResources) { |
|
||||||
SourceSet mainSourceSet = SourceSets.findMainSourceSet(getProject()); |
|
||||||
final File outputDir = (mainSourceSet == null ? null : mainSourceSet |
|
||||||
.getOutput().getResourcesDir()); |
|
||||||
final Set<File> resources = new LinkedHashSet<File>(); |
|
||||||
if (mainSourceSet != null) { |
|
||||||
resources.addAll(mainSourceSet.getResources().getSrcDirs()); |
|
||||||
} |
|
||||||
List<File> classPath = new ArrayList<File>(getClasspath().getFiles()); |
|
||||||
classPath.addAll(0, resources); |
|
||||||
getLogger().info("Adding classpath: " + resources); |
|
||||||
setClasspath(new SimpleFileCollection(classPath)); |
|
||||||
if (outputDir != null) { |
|
||||||
for (File directory : resources) { |
|
||||||
FileUtils.removeDuplicatesFromOutputDirectory(outputDir, directory); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,103 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.springframework.boot.gradle.run; |
|
||||||
|
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
import org.gradle.api.DefaultTask; |
|
||||||
import org.gradle.api.Project; |
|
||||||
import org.gradle.api.Task; |
|
||||||
import org.gradle.api.plugins.ApplicationPluginConvention; |
|
||||||
import org.gradle.api.tasks.SourceSet; |
|
||||||
import org.gradle.api.tasks.TaskAction; |
|
||||||
import org.springframework.boot.gradle.SpringBootPluginExtension; |
|
||||||
import org.springframework.boot.loader.tools.MainClassFinder; |
|
||||||
|
|
||||||
/** |
|
||||||
* Task to find and set the 'mainClassName' convention when it's missing by searching the |
|
||||||
* main source code. |
|
||||||
* |
|
||||||
* @author Dave Syer |
|
||||||
* @author Phillip Webb |
|
||||||
*/ |
|
||||||
public class FindMainClassTask extends DefaultTask { |
|
||||||
|
|
||||||
@TaskAction |
|
||||||
public void setMainClassNameProperty() { |
|
||||||
Project project = getProject(); |
|
||||||
if (project.property("mainClassName") == null) { |
|
||||||
project.setProperty("mainClassName", findMainClass()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private String findMainClass() { |
|
||||||
Project project = getProject(); |
|
||||||
|
|
||||||
String mainClass = null; |
|
||||||
|
|
||||||
// Try the SpringBoot extension setting
|
|
||||||
SpringBootPluginExtension bootExtension = project.getExtensions().getByType( |
|
||||||
SpringBootPluginExtension.class); |
|
||||||
if (bootExtension.getMainClass() != null) { |
|
||||||
mainClass = bootExtension.getMainClass(); |
|
||||||
} |
|
||||||
|
|
||||||
ApplicationPluginConvention application = (ApplicationPluginConvention) project |
|
||||||
.getConvention().getPlugins().get("application"); |
|
||||||
// Try the Application extension setting
|
|
||||||
if (mainClass == null && application.getMainClassName() != null) { |
|
||||||
mainClass = application.getMainClassName(); |
|
||||||
} |
|
||||||
|
|
||||||
Task runTask = getProject().getTasks().getByName("run"); |
|
||||||
if (mainClass == null && runTask.hasProperty("main")) { |
|
||||||
mainClass = (String) runTask.property("main"); |
|
||||||
} |
|
||||||
|
|
||||||
if (mainClass == null) { |
|
||||||
// Search
|
|
||||||
SourceSet mainSourceSet = SourceSets.findMainSourceSet(project); |
|
||||||
if (mainSourceSet != null) { |
|
||||||
project.getLogger().debug( |
|
||||||
"Looking for main in: " |
|
||||||
+ mainSourceSet.getOutput().getClassesDir()); |
|
||||||
try { |
|
||||||
mainClass = MainClassFinder.findSingleMainClass(mainSourceSet |
|
||||||
.getOutput().getClassesDir()); |
|
||||||
project.getLogger().info("Computed main class: " + mainClass); |
|
||||||
} |
|
||||||
catch (IOException ex) { |
|
||||||
throw new IllegalStateException("Cannot find main class", ex); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
project.getLogger().info("Found main: " + mainClass); |
|
||||||
|
|
||||||
if (bootExtension.getMainClass() == null) { |
|
||||||
bootExtension.setMainClass(mainClass); |
|
||||||
} |
|
||||||
if (application.getMainClassName() == null) { |
|
||||||
application.setMainClassName(mainClass); |
|
||||||
} |
|
||||||
if (!runTask.hasProperty("main")) { |
|
||||||
runTask.setProperty("main", mainClass); |
|
||||||
} |
|
||||||
|
|
||||||
return mainClass; |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,85 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.springframework.boot.gradle.run; |
|
||||||
|
|
||||||
import java.util.Collections; |
|
||||||
import java.util.concurrent.Callable; |
|
||||||
|
|
||||||
import org.gradle.api.Action; |
|
||||||
import org.gradle.api.Project; |
|
||||||
import org.gradle.api.Task; |
|
||||||
import org.gradle.api.plugins.JavaPluginConvention; |
|
||||||
import org.gradle.api.tasks.JavaExec; |
|
||||||
import org.gradle.api.tasks.application.CreateStartScripts; |
|
||||||
import org.springframework.boot.gradle.PluginFeatures; |
|
||||||
|
|
||||||
/** |
|
||||||
* {@link PluginFeatures} to add run support. |
|
||||||
* |
|
||||||
* @author Phillip Webb |
|
||||||
*/ |
|
||||||
public class RunPluginFeatures implements PluginFeatures { |
|
||||||
|
|
||||||
private static final String FIND_MAIN_CLASS_TASK_NAME = "findMainClass"; |
|
||||||
|
|
||||||
private static final String RUN_APP_TASK_NAME = "bootRun"; |
|
||||||
|
|
||||||
@Override |
|
||||||
public void apply(Project project) { |
|
||||||
mainClassNameFinder(project); |
|
||||||
addBootRunTask(project); |
|
||||||
} |
|
||||||
|
|
||||||
private void mainClassNameFinder(Project project) { |
|
||||||
project.getTasks().create(FIND_MAIN_CLASS_TASK_NAME, FindMainClassTask.class); |
|
||||||
project.getTasks().all(new Action<Task>() { |
|
||||||
@Override |
|
||||||
public void execute(Task task) { |
|
||||||
if (task instanceof JavaExec || task instanceof CreateStartScripts) { |
|
||||||
task.dependsOn(FIND_MAIN_CLASS_TASK_NAME); |
|
||||||
} |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
private void addBootRunTask(final Project project) { |
|
||||||
final JavaPluginConvention javaConvention = project.getConvention().getPlugin( |
|
||||||
JavaPluginConvention.class); |
|
||||||
|
|
||||||
BootRunTask run = project.getTasks().create(RUN_APP_TASK_NAME, BootRunTask.class); |
|
||||||
run.setDescription("Run the project with support for " |
|
||||||
+ "auto-detecting main class and reloading static resources"); |
|
||||||
run.setGroup("application"); |
|
||||||
run.setClasspath(javaConvention.getSourceSets().findByName("main") |
|
||||||
.getRuntimeClasspath()); |
|
||||||
run.getConventionMapping().map("main", new Callable<Object>() { |
|
||||||
@Override |
|
||||||
public Object call() throws Exception { |
|
||||||
return project.property("mainClassName"); |
|
||||||
} |
|
||||||
}); |
|
||||||
run.getConventionMapping().map("jvmArgs", new Callable<Object>() { |
|
||||||
@Override |
|
||||||
public Object call() throws Exception { |
|
||||||
if (project.hasProperty("applicationDefaultJvmArgs")) { |
|
||||||
return project.property("applicationDefaultJvmArgs"); |
|
||||||
} |
|
||||||
return Collections.emptyList(); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,51 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.springframework.boot.gradle.run; |
|
||||||
|
|
||||||
import java.util.Collections; |
|
||||||
|
|
||||||
import org.gradle.api.Project; |
|
||||||
import org.gradle.api.plugins.JavaPluginConvention; |
|
||||||
import org.gradle.api.tasks.SourceSet; |
|
||||||
|
|
||||||
/** |
|
||||||
* Utilities for working with {@link SourceSet}s. |
|
||||||
* |
|
||||||
* @author Dave Syer |
|
||||||
* @author Phillip Webb |
|
||||||
*/ |
|
||||||
class SourceSets { |
|
||||||
|
|
||||||
public static SourceSet findMainSourceSet(Project project) { |
|
||||||
for (SourceSet sourceSet : getJavaSourceSets(project)) { |
|
||||||
if (SourceSet.MAIN_SOURCE_SET_NAME.equals(sourceSet.getName())) { |
|
||||||
return sourceSet; |
|
||||||
} |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
private static Iterable<SourceSet> getJavaSourceSets(Project project) { |
|
||||||
JavaPluginConvention plugin = project.getConvention().getPlugin( |
|
||||||
JavaPluginConvention.class); |
|
||||||
if (plugin == null) { |
|
||||||
return Collections.emptyList(); |
|
||||||
} |
|
||||||
return plugin.getSourceSets(); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
Loading…
Reference in new issue