Home / Class/ ResolveMainClassName Class — spring-boot Architecture

ResolveMainClassName Class — spring-boot Architecture

Architecture documentation for the ResolveMainClassName class in ResolveMainClassName.java from the spring-boot codebase.

Entity Profile

Source Code

build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/ResolveMainClassName.java lines 54–190

@DisableCachingByDefault(because = "Not worth caching")
public class ResolveMainClassName extends DefaultTask {

	private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication";

	private final RegularFileProperty outputFile;

	private final Property<String> configuredMainClass;

	private @Nullable FileCollection classpath;

	/**
	 * Creates a new instance of the {@code ResolveMainClassName} task.
	 */
	public ResolveMainClassName() {
		this.outputFile = getProject().getObjects().fileProperty();
		this.configuredMainClass = getProject().getObjects().property(String.class);
	}

	/**
	 * Returns the classpath that the task will examine when resolving the main class
	 * name.
	 * @return the classpath
	 */
	@Classpath
	public FileCollection getClasspath() {
		Assert.state(this.classpath != null, "'classpath' must not be null");
		return this.classpath;
	}

	/**
	 * Sets the classpath that the task will examine when resolving the main class name.
	 * @param classpath the classpath
	 */
	public void setClasspath(FileCollection classpath) {
		setClasspath((Object) classpath);
	}

	/**
	 * Sets the classpath that the task will examine when resolving the main class name.
	 * The given {@code classpath} is evaluated as per {@link Project#files(Object...)}.
	 * @param classpath the classpath
	 * @since 2.5.10
	 */
	public void setClasspath(Object classpath) {
		this.classpath = getProject().files(classpath);
	}

	/**
	 * Returns the property for the task's output file that will contain the name of the
	 * main class.
	 * @return the output file
	 */
	@OutputFile
	public RegularFileProperty getOutputFile() {
		return this.outputFile;
	}

	/**
	 * Returns the property for the explicitly configured main class name that should be
	 * used in favor of resolving the main class name from the classpath.
	 * @return the configured main class name property
	 */
	@Input
	@Optional
	public Property<String> getConfiguredMainClassName() {
		return this.configuredMainClass;
	}

	@TaskAction
	void resolveAndStoreMainClassName() throws IOException {
		File outputFile = this.outputFile.getAsFile().get();
		outputFile.getParentFile().mkdirs();
		String mainClassName = resolveMainClassName();
		Files.writeString(outputFile.toPath(), mainClassName, StandardOpenOption.WRITE, StandardOpenOption.CREATE,
				StandardOpenOption.TRUNCATE_EXISTING);
	}

	private String resolveMainClassName() {
		String configuredMainClass = this.configuredMainClass.getOrNull();
		if (configuredMainClass != null) {
			return configuredMainClass;
		}
		return getClasspath().filter(File::isDirectory)
			.getFiles()
			.stream()
			.map(this::findMainClass)
			.filter(Objects::nonNull)
			.findFirst()
			.orElse("");
	}

	private @Nullable String findMainClass(File file) {
		try {
			return MainClassFinder.findSingleMainClass(file, SPRING_BOOT_APPLICATION_CLASS_NAME);
		}
		catch (IOException ex) {
			return null;
		}
	}

	Provider<String> readMainClassName() {
		String classpath = getClasspath().filter(File::isDirectory)
			.getFiles()
			.stream()
			.map(File::getAbsolutePath)
			.collect(Collectors.joining(File.pathSeparator));
		return this.outputFile.map(new ClassNameReader(classpath));
	}

	private static final class ClassNameReader implements Transformer<String, RegularFile> {

		private final String classpath;

		private ClassNameReader(String classpath) {
			this.classpath = classpath;
		}

		@Override
		public String transform(RegularFile file) {
			if (file.getAsFile().length() == 0) {
				throw new InvalidUserDataException(
						"Main class name has not been configured and it could not be resolved from classpath "
								+ this.classpath);
			}
			Path output = file.getAsFile().toPath();
			try {
				return Files.readString(output);
			}
			catch (IOException ex) {
				throw new RuntimeException("Failed to read main class name from '" + output + "'");
			}
		}

	}

}

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free