上一篇Android Gradle学习(六)- gradle插件源码解析讲解了gradle插件如何创建的Task
,本篇继续探讨gradle Task
的执行过程。还是以com.android.tools.build:gradle:4.1.3
, gradle-api-6.8.jar
为例
学前思考
./gradlew assembleDebug
命令,编译器帮我们做了什么?Task
的顺序是如何构成的?Task
是如何执行的?
1. gradlew
文件
项目根目录下有gradlew
文件,./
是linux
执行该文件的命令,assembleDebug
是入参。
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
# gradlew
APP_BASE_NAME=`basename "$0"`
# 设置gradle-wrapper.jar路径
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# 获取JAVA_HOME的路径
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
# 执行Java命令,比如java -Xmx64m -Dorg.gradle.appname=gradlew -classpath $APP_HOME/gradle/wrapper/gradle-wrapper.jar org.gradle.wrapper.GradleWrapperMain 'assembleRelease'
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
之后一句命令,调用了gradle-wrapper.jar
,还可以看到主入口org.gradle.wrapper.GradleWrapperMain
2. gradle wrapper
gradle wrapper
是对gradle
的包装器,封装了gradle
的调用,好处有两点
- 横向:统一不同开发者编译当前项目的
gradle
版本 - 纵向:
gradle
版本升级时,不需要关心api
变动
上一步调用到了org.gradle.wrapper.GradleWrapperMain
public class GradleWrapperMain {
public static final String GRADLE_USER_HOME_OPTION = "g";
public static final String GRADLE_USER_HOME_DETAILED_OPTION = "gradle-user-home";
public static final String GRADLE_QUIET_OPTION = "q";
public static final String GRADLE_QUIET_DETAILED_OPTION = "quiet";
public GradleWrapperMain() {
}
// args是传入的`assembleDebug`
public static void main(String[] args) throws Exception {
// 找到gradle-wrapper.jar
File wrapperJar = wrapperJar();
// 找到gradle-wrapper.properties
File propertiesFile = wrapperProperties(wrapperJar);
File rootDir = rootDir(wrapperJar);
CommandLineParser parser = new CommandLineParser();
parser.allowUnknownOptions();
parser.option(new String[]{"g", "gradle-user-home"}).hasArgument();
parser.option(new String[]{"q", "quiet"});
SystemPropertiesCommandLineConverter converter = new SystemPropertiesCommandLineConverter();
converter.configure(parser);
ParsedCommandLine options = parser.parse(args);
Properties systemProperties = System.getProperties();
systemProperties.putAll(converter.convert(options, new HashMap()));
File gradleUserHome = gradleUserHome(options);
addSystemProperties(gradleUserHome, rootDir);
Logger logger = logger(options);
// 读取gradle/wrapper/gradle-wrapper.properties
WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile(propertiesFile, logger);
wrapperExecutor.execute(args, new Install(logger, new Download(logger, "gradlew", wrapperVersion()), new PathAssembler(gradleUserHome)), new BootstrapMainStarter());
}
}
private static void addSystemProperties(File gradleHome, File rootDir) {
// 全局的gradle.properties
System.getProperties().putAll(SystemPropertiesHandler.getSystemProperties(new File(gradleHome, "gradle.properties")));
// 当前项目的gradle.properties
System.getProperties().putAll(SystemPropertiesHandler.getSystemProperties(new File(rootDir, "gradle.properties")));
}
main
方法主要做了三件事:
- 加载
gradle-wrapper.jar
,gradle-wrapper.properties
- 加载并配置
gradle.properties
- 启动
gradle
编译流程
继续跟进WrapperExecutor
public void execute(String[] args, Install install, BootstrapMainStarter bootstrapMainStarter) throws Exception {
// gradle-wrapper.properties里面配置的gradle下载地址,判断是否已经下载过,没有则下载
File gradleHome = install.createDist(config);
// 引导启动器启动gradle编译
bootstrapMainStarter.start(args, gradleHome);
}
BootstrapMainStarter
:引导启动器
public void start(String[] args, File gradleHome) throws Exception {
File gradleJar = findLauncherJar(gradleHome);
if (gradleJar == null) {
throw new RuntimeException(String.format("Could not locate the Gradle launcher JAR in Gradle distribution '%s'.", gradleHome));
}
URLClassLoader contextClassLoader = new URLClassLoader(new URL[]{gradleJar.toURI().toURL()}, ClassLoader.getSystemClassLoader().getParent());
Thread.currentThread().setContextClassLoader(contextClassLoader);
Class<?> mainClass = contextClassLoader.loadClass("org.gradle.launcher.GradleMain");
Method mainMethod = mainClass.getMethod("main", String[].class);
mainMethod.invoke(null, new Object[]{args});
if (contextClassLoader instanceof Closeable) {
((Closeable) contextClassLoader).close();
}
}
可以看到使用反射调用了org.gradle.launcher.GradleMain
的main
方法,args
是传入的"assembleDebug
"字符串。至此gradle wrapper
的任务就完成了
3. gradle-api-6.8.jar
3.1 GradleMain
public class GradleMain {
public static void main(String[] args) {
try {
// 判断jdk版本,此处最低需要Java1.8
UnsupportedJavaRuntimeException.assertUsingVersion("Gradle", JavaVersion.VERSION_1_8);
} catch (UnsupportedJavaRuntimeException ex) {
System.err.println(ex.getMessage());
System.exit(1);
}
// args是传入的"assembleDebug"
new ProcessBootstrap().run("org.gradle.launcher.Main", args);
}
}
GradleMain
是gradle
编译的主入口,第一步检查jdk
版本,第二步使用ProcessBootstrap
启动主程序
ProcessBootStrap
public class ProcessBootstrap {
/**
* Sets up the ClassLoader structure for the given class, creates an instance and invokes {@link EntryPoint#run(String[])} on it.
*/
public void run(String mainClassName, String[] args) {
try {
runNoExit(mainClassName, args);
System.exit(0);
} catch (Throwable throwable) {
throwable.printStackTrace();
System.exit(1);
}
}
private void runNoExit(String mainClassName, String[] args) throws Exception {
// ...
try {
// 反射调用"org.gradle.launcher.Main"的"run"
Class<?> mainClass = runtimeClassLoader.loadClass(mainClassName);
Object entryPoint = mainClass.getConstructor().newInstance();
Method mainMethod = mainClass.getMethod("run", String[].class);
mainMethod.invoke(entryPoint, new Object[]{args});
} finally {
// ...
}
}
}
可以看到通过反射调用org.gradle.launcher.Main.run("assembleDebug")
3.2 Main
Main.java
public class Main extends EntryPoint {
public static void main(String[] args) {
new Main().run(args);
}
@Override
protected void doAction(String[] args, ExecutionListener listener) {
createActionFactory().convert(Arrays.asList(args)).execute(listener);
}
CommandLineActionFactory createActionFactory() {
return new DefaultCommandLineActionFactory();
}
}
此处执行了DefaultCommandLineActionFactory.WithLogging.execute()
@Override
public void execute(ExecutionListener executionListener) {
// ...
try {
解析args
ParsedCommandLine parsedCommandLine = parser.parse(args);
InitialProperties initialProperties = propertiesConverter.convert(parsedCommandLine);
// Calculate build layout, for loading properties and other logging configuration
buildLayout = buildLayoutConverter.convert(initialProperties, parsedCommandLine, null);
// 读取 *.properties 文件
AllProperties properties = layoutToPropertiesConverter.convert(initialProperties, buildLayout);
// Calculate the logging configuration
loggingBuildOptions.convert(parsedCommandLine, properties, loggingConfiguration);
} catch (CommandLineArgumentException e) {
// Ignore, deal with this problem later
}
LoggingManagerInternal loggingManager = loggingServices.getFactory(LoggingManagerInternal.class).create();
loggingManager.setLevelInternal(loggingConfiguration.getLogLevel());
loggingManager.start();
try {
Action<ExecutionListener> exceptionReportingAction =
new ExceptionReportingAction(reporter, loggingManager,
new NativeServicesInitializingAction(buildLayout, loggingConfiguration, loggingManager,
new WelcomeMessageAction(buildLayout,
new DebugLoggerWarningAction(loggingConfiguration, action))));
exceptionReportingAction.execute(executionListener);
} finally {
loggingManager.stop();
}
}
layoutToPropertiesConverter.convert
读取*.properties
文件
public AllProperties convert(InitialProperties initialProperties, BuildLayoutResult layout) {
BuildLayoutParameters layoutParameters = new BuildLayoutParameters();
layout.applyTo(layoutParameters);
Map<String, String> properties = new HashMap<>();
// 加载用户目录/.gradle/gradle.properties的属性
configureFromHomeDir(layoutParameters.getGradleInstallationHomeDir(), properties);
// 加载项目根目录/gradle.properties的属性
configureFromBuildDir(layoutParameters.getSearchDir(), layoutParameters.getSearchUpwards(), properties);
configureFromHomeDir(layout.getGradleUserHomeDir(), properties);
configureFromSystemPropertiesOfThisJvm(Cast.uncheckedNonnullCast(properties));
properties.putAll(initialProperties.getRequestedSystemProperties());
return new Result(properties, initialProperties);
}
此时回到DefaultCommandLineActionFactory execute()
,后续依次调用了
ExceptionReportingAction
NativeServicesInitializingAction
WelcomeMessageAction
DebugLoggerWarningAction
最后一个Action
执行完成之后,会执行WithLogging
构造体传入的action
,可以回到Main
查看DefaultCommandLineActionFactory convert
方法
@Override
public CommandLineExecution convert(List<String> args) {
ServiceRegistry loggingServices = createLoggingServices();
LoggingConfiguration loggingConfiguration = new DefaultLoggingConfiguration();
return new WithLogging(loggingServices,
args,
loggingConfiguration,
new ParseAndBuildAction(loggingServices, args),
new BuildExceptionReporter(loggingServices.get(StyledTextOutputFactory.class), loggingConfiguration, clientMetaData()));
}
action
是ParseAndBuildAction
,后续执行execute
方法
@Override
public void execute(ExecutionListener executionListener) {
// ...
Action<? super ExecutionListener> action;
try {
ParsedCommandLine commandLine = parser.parse(args);
// 创建构建action
action = createAction(actions, parser, commandLine);
} catch (CommandLineArgumentException e) {
action = new CommandLineParseFailureAction(parser, e);
}
action.execute(executionListener);
}
private Action<? super ExecutionListener> createAction(Iterable<CommandLineAction> factories, CommandLineParser parser, ParsedCommandLine commandLine) {
for (CommandLineAction factory : factories) {
Runnable action = factory.createAction(parser, commandLine);
if (action != null) {
return Actions.toAction(action);
}
}
throw new UnsupportedOperationException("No action factory for specified command-line arguments.");
}
可以看到调用createAction()
,此处调用了BuildActionsFactory createAction()
@Override
public Runnable createAction(CommandLineParser parser, ParsedCommandLine commandLine) {
// 创建assembleDebug任务
Parameters parameters = parametersConverter.convert(commandLine, null);
// ...
if (parameters.getDaemonParameters().isEnabled()) {
return runBuildWithDaemon(parameters.getStartParameter(), parameters.getDaemonParameters());
}
if (canUseCurrentProcess(parameters.getDaemonParameters())) {
return runBuildInProcess(parameters.getStartParameter(), parameters.getDaemonParameters());
}
return runBuildInSingleUseDaemon(parameters.getStartParameter(), parameters.getDaemonParameters());
}
parametersConverter.convert
跟进
// org.gradle.launcher.cli.ParametersConverter#convert
public Parameters convert(ParsedCommandLine args, @Nullable File currentDir) throws CommandLineArgumentException {
InitialProperties initialProperties = initialPropertiesConverter.convert(args);
BuildLayoutResult buildLayout = buildLayoutConverter.convert(initialProperties, args, currentDir);
AllProperties properties = layoutToPropertiesConverter.convert(initialProperties, buildLayout);
StartParameterInternal startParameter = new StartParameterInternal();
//
startParameterConverter.convert(args, buildLayout, properties, startParameter);
DaemonParameters daemonParameters = new DaemonParameters(buildLayout, fileCollectionFactory, properties.getRequestedSystemProperties());
daemonParametersConverter.convert(args, properties, daemonParameters);
return new Parameters(buildLayout, startParameter, daemonParameters);
}
// org.gradle.launcher.cli.converter.StartParameterConverter#convert
public StartParameterInternal convert(ParsedCommandLine parsedCommandLine, BuildLayoutResult buildLayout, AllProperties properties, StartParameterInternal startParameter) throws CommandLineArgumentException {
// ...
if (!parsedCommandLine.getExtraArguments().isEmpty()) {
// 任务名称设置为assembleDebug
startParameter.setTaskNames(parsedCommandLine.getExtraArguments());
}
buildOptionsConverter.convert(parsedCommandLine, properties, startParameter);
return startParameter;
}
回溯一级,看到createAction()
调用了runBuildInProcess()
private Runnable runBuildInProcess(StartParameterInternal startParameter, DaemonParameters daemonParameters) {
ServiceRegistry globalServices = ServiceRegistryBuilder.builder()
.displayName("Global services")
.parent(loggingServices)
.parent(NativeServices.getInstance())
.provider(new GlobalScopeServices(startParameter.isContinuous()))
.build();
// Force the user home services to be stopped first, the dependencies between the user home services and the global services are not preserved currently
return runBuildAndCloseServices(startParameter, daemonParameters, globalServices.get(BuildExecuter.class), globalServices, globalServices.get(GradleUserHomeScopeServiceRegistry.class));
}
private Runnable runBuildAndCloseServices(StartParameterInternal startParameter, DaemonParameters daemonParameters, BuildActionExecuter<BuildActionParameters, BuildRequestContext> executer, ServiceRegistry sharedServices, Object... stopBeforeSharedServices) {
BuildActionParameters parameters = createBuildActionParameters(startParameter, daemonParameters);
Stoppable stoppable = new CompositeStoppable().add(stopBeforeSharedServices).add(sharedServices);
return new RunBuildAction(executer, startParameter, clientMetaData(), getBuildStartTime(), parameters, sharedServices, stoppable);
}
此时返回了RunBuildAction
,后续调用其run
方法
@Override
public void run() {
try {
BuildActionResult result = executer.execute(
new ExecuteBuildAction(startParameter),
buildActionParameters,
new DefaultBuildRequestContext(new DefaultBuildRequestMetaData(clientMetaData, startTime, sharedServices.get(ConsoleDetector.class).isConsoleInput()), new DefaultBuildCancellationToken(), new NoOpBuildEventConsumer())
);
if (result.hasFailure()) {
// Don't need to unpack the serialized failure. It will already have been reported and is not used by anything downstream of this action.
throw new ReportedException();
}
} finally {
if (stoppable != null) {
stoppable.stop();
}
}
}
这个executer
是哪里来的?回溯下是globalServices.get(BuildExecuter.class)
,上面的BuildActionsFactory#runBuildInProcess()
创建的。
3.3 GlobalScopeServices
GlobalScopeServices.java
void configure(ServiceRegistration registration, ClassLoaderRegistry classLoaderRegistry) {
registration.add(ClassLoaderScopeListeners.class);
final List<PluginServiceRegistry> pluginServiceFactories = new DefaultServiceLocator(classLoaderRegistry.getRuntimeClassLoader(), classLoaderRegistry.getPluginsClassLoader()).getAll(PluginServiceRegistry.class);
for (PluginServiceRegistry pluginServiceRegistry : pluginServiceFactories) {
registration.add(PluginServiceRegistry.class, pluginServiceRegistry);
pluginServiceRegistry.registerGlobalServices(registration);
}
}
org.gradle.internal.service.DefaultServiceLocator#getAll
@Override
public <T> List<T> getAll(Class<T> serviceType) throws UnknownServiceException {
List<ServiceFactory<T>> factories = findFactoriesForServiceType(serviceType);
ArrayList<T> services = new ArrayList<T>();
for (ServiceFactory<T> factory : factories) {
services.add(factory.create());
}
return services;
}
private <T> List<ServiceFactory<T>> findFactoriesForServiceType(Class<T> serviceType) {
return factoriesFor(serviceType, implementationsOf(serviceType));
}
public <T> List<Class<? extends T>> implementationsOf(Class<T> serviceType) {
try {
return findServiceImplementations(serviceType);
} catch (ServiceLookupException e) {
throw e;
} catch (Exception e) {
throw new ServiceLookupException(String.format("Could not determine implementation classes for service '%s'.", serviceType.getName()), e);
}
}
private <T> List<Class<? extends T>> findServiceImplementations(Class<T> serviceType) throws IOException {
String resourceName = "META-INF/services/" + serviceType.getName();
Set<String> implementationClassNames = new HashSet<String>();
List<Class<? extends T>> implementations = new ArrayList<Class<? extends T>>();
for (ClassLoader classLoader : classLoaders) {
Enumeration<URL> resources = classLoader.getResources(resourceName);
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
List<String> implementationClassNamesFromResource;
try {
implementationClassNamesFromResource = extractImplementationClassNames(resource);
if (implementationClassNamesFromResource.isEmpty()) {
throw new RuntimeException(String.format("No implementation class for service '%s' specified.", serviceType.getName()));
}
} catch (Throwable e) {
throw new ServiceLookupException(String.format("Could not determine implementation class for service '%s' specified in resource '%s'.", serviceType.getName(), resource), e);
}
for (String implementationClassName : implementationClassNamesFromResource) {
if (implementationClassNames.add(implementationClassName)) {
try {
Class<?> implClass = classLoader.loadClass(implementationClassName);
if (!serviceType.isAssignableFrom(implClass)) {
throw new RuntimeException(String.format("Implementation class '%s' is not assignable to service class '%s'.", implementationClassName, serviceType.getName()));
}
implementations.add(implClass.asSubclass(serviceType));
} catch (Throwable e) {
throw new ServiceLookupException(String.format("Could not load implementation class '%s' for service '%s' specified in resource '%s'.", implementationClassName, serviceType.getName(), resource), e);
}
}
}
}
}
return implementations;
}
可以看到resourceName
= "META-INF/services/org.gradle.internal.service.scopes.PluginServiceRegistry"
,去源码目录找到
找到LauncherServices.java
3.4 LauncherServices
public class LauncherServices extends AbstractPluginServiceRegistry {
@Override
public void registerGlobalServices(ServiceRegistration registration) {
registration.addProvider(new ToolingGlobalScopeServices());
}
}
此时注册了LauncherServices
的服务,那么globalServices.get(BuildExecuter.class)
就是去找executer
// org.gradle.launcher.cli.BuildActionsFactory#runBuildInProcess
private Runnable runBuildInProcess(StartParameterInternal startParameter, DaemonParameters daemonParameters) {
ServiceRegistry globalServices = ServiceRegistryBuilder.builder()
.displayName("Global services")
.parent(loggingServices)
.parent(NativeServices.getInstance())
.provider(new GlobalScopeServices(startParameter.isContinuous()))
.build();
// Force the user home services to be stopped first, the dependencies between the user home services and the global services are not preserved currently
return runBuildAndCloseServices(startParameter, daemonParameters, globalServices.get(BuildExecuter.class), globalServices, globalServices.get(GradleUserHomeScopeServiceRegistry.class));
}
// org.gradle.internal.service.ServiceRegistryBuilder#build
public ServiceRegistry build() {
DefaultServiceRegistry registry = new DefaultServiceRegistry(displayName, parents.toArray(new ServiceRegistry[0]));
for (Object provider : providers) {
registry.addProvider(provider);
}
return registry;
}
此处是DefaultServiceRegistry.get(BuildExecuter.class)
// org.gradle.internal.service.DefaultServiceRegistry#get(java.lang.Class<T>)
@Override
public <T> T get(Class<T> serviceType) throws UnknownServiceException, ServiceLookupException {
return serviceType.cast(get((Type) serviceType));
}
@Override
public Object get(Type serviceType) throws UnknownServiceException, ServiceLookupException {
Object instance = find(serviceType);
if (instance == null) {
throw new UnknownServiceException(serviceType, String.format("No service of type %s available in %s.", format(serviceType), getDisplayName()));
}
return instance;
}
@Override
public Object find(Type serviceType) throws ServiceLookupException {
assertValidServiceType(unwrap(serviceType));
Service provider = getService(serviceType);
return provider == null ? null : provider.get();
}
private Service getService(Type serviceType) {
serviceRequested();
return find(serviceType, allServices);
}
private static Service find(Type serviceType, ServiceProvider serviceProvider) {
if (serviceType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) serviceType;
Type rawType = parameterizedType.getRawType();
if (rawType.equals(Factory.class)) {
final Type typeArg = parameterizedType.getActualTypeArguments()[0];
return getFactoryService(typeArg, serviceProvider);
}
if (rawType instanceof Class) {
if (((Class<?>) rawType).isAssignableFrom(List.class)) {
Type typeArg = parameterizedType.getActualTypeArguments()[0];
return getCollectionService(typeArg, serviceProvider);
}
assertValidServiceType((Class<?>) rawType);
return serviceProvider.getService(serviceType);
}
}
if (serviceType instanceof Class<?>) {
assertValidServiceType((Class<?>) serviceType);
return serviceProvider.getService(serviceType);
}
throw new ServiceValidationException(String.format("Locating services with type %s is not supported.", format(serviceType)));
}
看到是通过反射来匹配方法的返回值
找到LauncherServices.java
,注册了ToolingGlobalScopeServices
,里面createBuildExecuter
返回值就是BuildExecuter
类型
public class LauncherServices extends AbstractPluginServiceRegistry {
@Override
public void registerGlobalServices(ServiceRegistration registration) {
registration.addProvider(new ToolingGlobalScopeServices());
}
static class ToolingGlobalScopeServices {
BuildExecuter createBuildExecuter(StyledTextOutputFactory styledTextOutputFactory,
LoggingManagerInternal loggingManager,
GradleUserHomeScopeServiceRegistry userHomeServiceRegistry,
ServiceRegistry globalServices) {
// @formatter:off
return
new SetupLoggingActionExecuter(loggingManager,
new SessionFailureReportingActionExecuter(styledTextOutputFactory, Time.clock(),
// 校验settings.gradle等文件是否存在
new StartParamsValidatingActionExecuter(
new GradleThreadBuildActionExecuter(
new SessionScopeLifecycleBuildActionExecuter(userHomeServiceRegistry, globalServices
)))));
// @formatter:on
}
FileSystemChangeWaiterFactory createFileSystemChangeWaiterFactory(FileWatcherFactory fileWatcherFactory) {
return new DefaultFileSystemChangeWaiterFactory(fileWatcherFactory);
}
ExecuteBuildActionRunner createExecuteBuildActionRunner() {
return new ExecuteBuildActionRunner();
}
ClassLoaderCache createClassLoaderCache() {
return new ClassLoaderCache();
}
}
}
createBuildExecuter
也是一个链式调用 SessionScopeLifecycleBuildActionExecuter.execute()
@Override
public BuildActionResult execute(BuildAction action, BuildActionParameters actionParameters, BuildRequestContext requestContext) {
StartParameter startParameter = action.getStartParameter();
try (CrossBuildSessionState crossBuildSessionState = new CrossBuildSessionState(globalServices, startParameter)) {
try (BuildSessionState buildSessionState = new BuildSessionState(userHomeServiceRegistry, crossBuildSessionState, startParameter, requestContext, actionParameters.getInjectedPluginClasspath(), requestContext.getCancellationToken(), requestContext.getClient(), requestContext.getEventConsumer())) {
return buildSessionState.run(context -> {
SessionLifecycleListener sessionLifecycleListener = context.getServices().get(ListenerManager.class).getBroadcaster(SessionLifecycleListener.class);
try {
sessionLifecycleListener.afterStart();
return context.getServices().get(SessionScopeBuildActionExecutor.class).execute(action, actionParameters, context);
} finally {
sessionLifecycleListener.beforeComplete();
}
});
}
}
}
调用了context.getServices().get(SessionScopeBuildActionExecutor.class)
,SessionScopeBuildActionExecutor
的服务是在LauncherServices.java
注册的
static class ToolingBuildSessionScopeServices {
SessionScopeBuildActionExecutor createActionExecutor(BuildEventListenerFactory listenerFactory,
ExecutorFactory executorFactory,
ListenerManager listenerManager,
BuildOperationListenerManager buildOperationListenerManager,
TaskInputsListeners inputsListeners,
StyledTextOutputFactory styledTextOutputFactory,
FileSystemChangeWaiterFactory fileSystemChangeWaiterFactory,
BuildRequestMetaData requestMetaData,
BuildCancellationToken cancellationToken,
DeploymentRegistryInternal deploymentRegistry,
BuildEventConsumer eventConsumer,
BuildStartedTime buildStartedTime,
Clock clock
) {
return new SubscribableBuildActionExecuter(listenerManager, buildOperationListenerManager, listenerFactory, eventConsumer,
new ContinuousBuildActionExecuter(fileSystemChangeWaiterFactory, inputsListeners, styledTextOutputFactory, executorFactory, requestMetaData, cancellationToken, deploymentRegistry, listenerManager, buildStartedTime, clock,
new BuildTreeScopeLifecycleBuildActionExecuter()));
}
}
BuildTreeScopeLifecycleBuildActionExecuter#execute()
@Override
public BuildActionResult execute(BuildAction action, BuildActionParameters actionParameters, BuildSessionContext buildSession) {
BuildType buildType = action.isRunTasks() ? BuildType.TASKS : BuildType.MODEL;
try (BuildTreeState buildTree = new BuildTreeState(buildSession.getServices(), buildType)) {
return buildTree.run(context ->
context.getBuildTreeServices().get(BuildTreeBuildActionExecutor.class).execute(action, actionParameters, context));
}
}
BuildTreeBuildActionExecutor#execute()
static class ToolingBuildTreeScopeServices {
BuildTreeBuildActionExecutor createActionExecuter(List<BuildActionRunner> buildActionRunners,
StyledTextOutputFactory styledTextOutputFactory,
BuildStateRegistry buildStateRegistry,
PayloadSerializer payloadSerializer,
BuildOperationNotificationValve buildOperationNotificationValve,
BuildCancellationToken buildCancellationToken
) {
return new InProcessBuildActionExecuter(buildStateRegistry, payloadSerializer, buildOperationNotificationValve, buildCancellationToken,
new RunAsBuildOperationBuildActionRunner(
new BuildCompletionNotifyingBuildActionRunner(
new FileSystemWatchingBuildActionRunner(
new ValidatingBuildActionRunner(
new BuildOutcomeReportingBuildActionRunner(styledTextOutputFactory,
new ChainingBuildActionRunner(buildActionRunners)))))));
}
}
InProcessBuildActionExecuter&execute()
@Override
public BuildActionResult execute(BuildAction action, BuildActionParameters actionParameters, BuildTreeContext buildTree) {
buildOperationNotificationValve.start();
try {
RootBuildState rootBuild = buildStateRegistry.createRootBuild(BuildDefinition.fromStartParameter(action.getStartParameter(), null));
return rootBuild.run(buildController -> {
BuildActionRunner.Result result = buildActionRunner.run(action, buildController);
if (result.getBuildFailure() == null) {
return BuildActionResult.of(payloadSerializer.serialize(result.getClientResult()));
}
if (buildCancellationToken.isCancellationRequested()) {
return BuildActionResult.cancelled(payloadSerializer.serialize(result.getBuildFailure()));
}
return BuildActionResult.failed(payloadSerializer.serialize(result.getClientFailure()));
});
} finally {
buildOperationNotificationValve.stop();
}
}
buildStateRegistry.createRootBuild()
,buildStateRegistry
是 DefaultIncludedBuildRegistry
@Override
public RootBuildState createRootBuild(BuildDefinition buildDefinition) {
if (rootBuild != null) {
throw new IllegalStateException("Root build already defined.");
}
rootBuild = new DefaultRootBuildState(buildDefinition, gradleLauncherFactory, listenerManager, owner);
addBuild(rootBuild);
return rootBuild;
}
DefaultRootBuildState.java
DefaultRootBuildState(BuildDefinition buildDefinition, GradleLauncherFactory gradleLauncherFactory, ListenerManager listenerManager, BuildTreeState owner) {
this.listenerManager = listenerManager;
this.gradleLauncher = gradleLauncherFactory.newInstance(buildDefinition, this, owner);
}
DefaultGradleLauncherFactory#newInstance
public GradleLauncher newInstance(BuildDefinition buildDefinition, RootBuildState build, BuildTreeState owner) {
// This should only be used for top-level builds
if (rootBuild != null) {
throw new IllegalStateException("Cannot have a current root build");
}
GradleLauncher launcher = doNewInstance(buildDefinition, build, null, owner, ImmutableList.of((Stoppable) () -> rootBuild = null));
rootBuild = launcher;
final DefaultDeploymentRegistry deploymentRegistry = owner.getServices().get(DefaultDeploymentRegistry.class);
launcher.getGradle().addBuildListener(new InternalBuildAdapter() {
@Override
public void buildFinished(BuildResult result) {
deploymentRegistry.buildFinished(result);
}
});
return launcher;
}
private GradleLauncher doNewInstance(
BuildDefinition buildDefinition,
BuildState owner,
@Nullable GradleLauncher parent,
BuildTreeState buildTree,
List<?> servicesToStop
) {
return doNewInstance(
buildDefinition,
owner,
parent,
buildTree,
servicesToStop,
this::createDefaultGradleLauncher,
BuildScopeServices::new
);
}
最终调用createDefaultGradleLauncher
,创建DefaultGradleLauncher
private GradleLauncher createDefaultGradleLauncher(
GradleInternal gradle,
BuildScopeServices serviceRegistry,
List<?> servicesToStop
) {
IncludedBuildControllers includedBuildControllers = gradle.getServices().get(IncludedBuildControllers.class);
ProjectsPreparer projectsPreparer = serviceRegistry.get(ProjectsPreparer.class);
SettingsPreparer settingsPreparer = serviceRegistry.get(SettingsPreparer.class);
TaskExecutionPreparer taskExecutionPreparer = gradle.getServices().get(TaskExecutionPreparer.class);
final ListenerManager listenerManager = serviceRegistry.get(ListenerManager.class);
return new DefaultGradleLauncher(
gradle,
projectsPreparer,
serviceRegistry.get(ExceptionAnalyser.class),
gradle.getBuildListenerBroadcaster(),
listenerManager.getBroadcaster(BuildCompletionListener.class),
listenerManager.getBroadcaster(InternalBuildFinishedListener.class),
gradle.getServices().get(BuildWorkExecutor.class),
serviceRegistry,
servicesToStop,
includedBuildControllers,
settingsPreparer,
taskExecutionPreparer,
gradle.getServices().get(ConfigurationCache.class),
new BuildOptionBuildOperationProgressEventsEmitter(
gradle.getServices().get(BuildOperationProgressEventEmitter.class)
)
);
}
里面获取的服务基本都是在BuildScopeServices
里面
3.5 DefaultGradleLauncher
生命周期
public class DefaultGradleLauncher implements GradleLauncher {
private enum Stage {
LoadSettings, Configure, TaskGraph, RunTasks() {
@Override
String getDisplayName() {
return "Build";
}
}, Finished;
String getDisplayName() {
return name();
}
}
}
LoadSettings
: 加载Configure
: 配置TaskGraph
: 生成Task执行图RunTasks
: 执行TaskFinished
: 完成
private void doClassicBuildStages(Stage upTo) {
if (stage == null) {
configurationCache.prepareForConfiguration();
}
prepareSettings();
if (upTo == Stage.LoadSettings) {
return;
}
prepareProjects();
if (upTo == Stage.Configure) {
return;
}
prepareTaskExecution();
if (upTo == Stage.TaskGraph) {
return;
}
configurationCache.save();
runWork();
}
3.5.1 LoadSettings
阶段
加载setting配置
private void prepareSettings() {
if (stage == null) {
buildListener.buildStarted(gradle);
settingsPreparer.prepareSettings(gradle);
stage = Stage.LoadSettings;
}
}
settingsPreparer
是serviceRegistry.get(SettingsPreparer.class)
,找到BuildScopeServices#createSettingsPreparer()
protected SettingsPreparer createSettingsPreparer(InitScriptHandler initScriptHandler, SettingsLoaderFactory settingsLoaderFactory, BuildOperationExecutor buildOperationExecutor, BuildDefinition buildDefinition) {
return new BuildOperationFiringSettingsPreparer(
new DefaultSettingsPreparer(
initScriptHandler,
settingsLoaderFactory
),
buildOperationExecutor,
buildDefinition.getFromBuild());
}
DefaultSettingsPreparer#prepareSettings
public void prepareSettings(GradleInternal gradle) {
// Evaluate init scripts
initScriptHandler.executeScripts(gradle);
// Build `buildSrc`, load settings.gradle, and construct composite (if appropriate)
SettingsLoader settingsLoader = gradle.isRootBuild() ? settingsLoaderFactory.forTopLevelBuild() : settingsLoaderFactory.forNestedBuild();
settingsLoader.findAndLoadSettings(gradle);
}
@Override
public SettingsLoader forTopLevelBuild() {
return new CompositeBuildSettingsLoader(
new ChildBuildRegisteringSettingsLoader(
new CommandLineIncludedBuildSettingsLoader(
defaultSettingsLoader()
),
buildRegistry,
publicBuildPath,
instantiator
),
buildRegistry);
}
@Override
public SettingsLoader forNestedBuild() {
return new ChildBuildRegisteringSettingsLoader(
defaultSettingsLoader(),
buildRegistry,
publicBuildPath,
instantiator
);
}
private SettingsLoader defaultSettingsLoader() {
return new SettingsAttachingSettingsLoader(
new DefaultSettingsLoader(
settingsProcessor,
buildLayoutFactory,
gradlePropertiesController
),
projectRegistry
);
}
DefaultSettingsLoader
加载root
的gradle.properties
和settings
,ChildBuildRegisteringSettingsLoader
遍历子module
创建project
对象
// DefaultGradleLauncher
// projectsPreparer是DefaultGradleLauncherFactory创建DefaultGradleLauncher时传入的
private void prepareProjects() {
if (stage == Stage.LoadSettings) {
projectsPreparer.prepareProjects(gradle);
stage = Stage.Configure;
}
}
// DefaultGradleLauncherFactory
private GradleLauncher createDefaultGradleLauncher() {
ProjectsPreparer projectsPreparer = serviceRegistry.get(ProjectsPreparer.class);
}
// BuildScopeServices
// 入参BuildLoader由服务创建
ProjectsPreparer createBuildConfigurer(..,BuildLoader buildLoader) {
return new BuildOperationFiringProjectsPreparer(
new BuildTreePreparingProjectsPreparer(
new DefaultProjectsPreparer(
projectConfigurer,
modelConfigurationListener,
buildOperationExecutor),
buildLoader,
buildStateRegistry,
buildSourceBuilder),
buildOperationExecutor);
}
// BuildScopeServices
protected BuildLoader createBuildLoader(GradleProperties gradleProperties, IProjectFactory projectFactory, BuildOperationExecutor buildOperationExecutor) {
return new NotifyingBuildLoader(
new ProjectPropertySettingBuildLoader(
gradleProperties,
new InstantiatingBuildLoader(
projectFactory
)
),
buildOperationExecutor
);
}
// InstantiatingBuildLoader
public void load(SettingsInternal settings, GradleInternal gradle) {
createProjects(gradle, settings.getRootProject());
attachDefaultProject(gradle, settings.getDefaultProject());
}
private void createProjects(GradleInternal gradle, ProjectDescriptor rootProjectDescriptor) {
ClassLoaderScope baseProjectClassLoaderScope = gradle.baseProjectClassLoaderScope();
ClassLoaderScope rootProjectClassLoaderScope = baseProjectClassLoaderScope.createChild("root-project");
ProjectInternal rootProject = projectFactory.createProject(gradle, rootProjectDescriptor, null, rootProjectClassLoaderScope, baseProjectClassLoaderScope);
gradle.setRootProject(rootProject);
createChildProjectsRecursively(gradle, rootProject, rootProjectDescriptor, rootProjectClassLoaderScope, baseProjectClassLoaderScope);
}
// ProjectFactory
public ProjectInternal createProject(GradleInternal gradle, ProjectDescriptor projectDescriptor, @Nullable ProjectInternal parent, ClassLoaderScope selfClassLoaderScope, ClassLoaderScope baseClassLoaderScope) {
Path projectPath = ((DefaultProjectDescriptor) projectDescriptor).path();
ProjectState projectContainer = projectStateRegistry.stateFor(owner.getBuildIdentifier(), projectPath);
File buildFile = projectDescriptor.getBuildFile();
TextResource resource = textFileResourceLoader.loadFile("build file", buildFile);
ScriptSource source = new TextResourceScriptSource(resource);
DefaultProject project = instantiator.newInstance(DefaultProject.class,
projectDescriptor.getName(),
parent,
projectDescriptor.getProjectDir(),
buildFile,
source,
gradle,
projectContainer,
gradle.getServiceRegistryFactory(),
selfClassLoaderScope,
baseClassLoaderScope
);
project.beforeEvaluate(p -> {
NameValidator.validate(project.getName(), "project name", DefaultProjectDescriptor.INVALID_NAME_IN_INCLUDE_HINT);
gradle.getServices().get(DependencyResolutionManagementInternal.class).configureProject(project);
});
if (parent != null) {
parent.addChildProject(project);
}
projectRegistry.addProject(project);
projectContainer.attachMutableModel(project);
return project;
}
至此加载阶段结束。主要加载了setting
配置文件和创建Project
对象。
3.5.2 Configure
阶段
// DefaultGradleLauncher
private void prepareTaskExecution() {
if (stage == Stage.Configure) {
taskExecutionPreparer.prepareForTaskExecution(gradle);
stage = Stage.TaskGraph;
}
}
// GradleScopeServices
TaskExecutionPreparer createTaskExecutionPreparer(BuildConfigurationActionExecuter buildConfigurationActionExecuter, IncludedBuildControllers includedBuildControllers, BuildOperationExecutor buildOperationExecutor) {
return new BuildOperationFiringTaskExecutionPreparer(
new DefaultTaskExecutionPreparer(buildConfigurationActionExecuter, includedBuildControllers, buildOperationExecutor),
buildOperationExecutor);
}
// DefaultTaskExecutionPreparer#prepareProjects
@Override
public void prepareProjects(GradleInternal gradle) {
if (gradle.getStartParameter().isConfigureOnDemand()) {
IncubationLogger.incubatingFeatureUsed("Configuration on demand");
projectConfigurer.configure(gradle.getRootProject());
} else {
projectConfigurer.configureHierarchy(gradle.getRootProject());
new ProjectsEvaluatedNotifier(buildOperationExecutor).notify(gradle);
}
modelConfigurationListener.onConfigure(gradle);
}
// projectConfigurer来自
protected ProjectConfigurer createProjectConfigurer(BuildCancellationToken cancellationToken) {
return new TaskPathProjectEvaluator(cancellationToken);
}
// TaskPathProjectEvaluator#configure
@Override
public void configure(ProjectInternal project) {
if (cancellationToken.isCancellationRequested()) {
throw new BuildCancelledException();
}
// Need to configure intermediate parent projects for configure-on-demand
ProjectInternal parentProject = project.getParent();
if (parentProject != null) {
configure(parentProject);
}
project.evaluate();
}
// DefaultProject#evaluate
public DefaultProject evaluate() {
// projectEvaluator = services.get(ProjectEvaluator.class);
getProjectEvaluator().evaluate(this, state);
return this;
}
// BuildScopeServices#createProjectEvaluator
protected ProjectEvaluator createProjectEvaluator(BuildOperationExecutor buildOperationExecutor, CachingServiceLocator cachingServiceLocator, ScriptPluginFactory scriptPluginFactory) {
ConfigureActionsProjectEvaluator withActionsEvaluator = new ConfigureActionsProjectEvaluator(
PluginsProjectConfigureActions.from(cachingServiceLocator),
new BuildScriptProcessor(scriptPluginFactory),
new DelayedConfigurationActions()
);
return new LifecycleProjectEvaluator(buildOperationExecutor, withActionsEvaluator);
}
// LifecycleProjectEvaluator#evaluate
public void evaluate(final ProjectInternal project, final ProjectStateInternal state) {
if (state.isUnconfigured()) {
buildOperationExecutor.run(new EvaluateProject(project, state));
}
}
// EvaluateProject#run
public void run(final BuildOperationContext context) {
project.getMutationState().applyToMutableState(p -> {
// Note: beforeEvaluate and afterEvaluate ops do not throw, instead mark state as failed
try {
state.toBeforeEvaluate();
buildOperationExecutor.run(new NotifyBeforeEvaluate(project, state));
if (!state.hasFailure()) {
state.toEvaluate();
try {
delegate.evaluate(project, state);
} catch (Exception e) {
addConfigurationFailure(project, state, e, context);
} finally {
state.toAfterEvaluate();
buildOperationExecutor.run(new NotifyAfterEvaluate(project, state));
}
}
if (state.hasFailure()) {
state.rethrowFailure();
} else {
context.setResult(ConfigureProjectBuildOperationType.RESULT);
}
} finally {
state.configured();
}
});
}
// delegate.evaluate(project, state); delegate是ConfigureActionsProjectEvaluator
public void evaluate(ProjectInternal project, ProjectStateInternal state) {
for (ProjectConfigureAction configureAction : configureActions) {
configureAction.execute(project);
}
}
ConfigureActionsProjectEvaluator
构造体传入了一些action
protected ProjectEvaluator createProjectEvaluator(BuildOperationExecutor buildOperationExecutor, CachingServiceLocator cachingServiceLocator, ScriptPluginFactory scriptPluginFactory) {
ConfigureActionsProjectEvaluator withActionsEvaluator = new ConfigureActionsProjectEvaluator(
PluginsProjectConfigureActions.from(cachingServiceLocator),
new BuildScriptProcessor(scriptPluginFactory),
new DelayedConfigurationActions()
);
return new LifecycleProjectEvaluator(buildOperationExecutor, withActionsEvaluator);
}
PluginsProjectConfigureActions#from
public static ProjectConfigureAction from(ServiceLocator serviceLocator) {
return of(ProjectConfigureAction.class, serviceLocator);
}
public static <T extends Action<ProjectInternal>> ProjectConfigureAction of(Class<T> serviceType,
ServiceLocator serviceLocator) {
return new PluginsProjectConfigureActions(
ImmutableList.<Action<ProjectInternal>>copyOf(
serviceLocator.getAll(serviceType)));
}
从serviceLocator
拷贝一些实现了ProjectConfigureAction
接口的action
MATE-INF/services/org.gradle.configuration.project.ProjectConfigureAction
看到一些服务
org.gradle.api.plugins.internal.HelpTasksAutoApplyAction
org.gradle.jvm.toolchain.internal.task.ShowToolchainsTaskConfigurator
org.gradle.buildinit.plugins.internal.action.BuildInitAutoApplyAction
org.gradle.buildinit.plugins.internal.action.WrapperPluginAutoApplyAction
以BuildInitAutoApplyAction
为例
public class BuildInitAutoApplyAction implements ProjectConfigureAction {
@Override
public void execute(final ProjectInternal project) {
project.getPluginManager().apply("org.gradle.build-init");
}
}
可以找到在META-INF/gralde-plugins/org.gradle.build-init.properties
implementation-class=org.gradle.buildinit.plugins.BuildInitPlugin
public class BuildInitPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
if (project.getParent() == null) {
project.getTasks().register("init", InitBuild.class, initBuild -> {
// ...
}
}
}
这里就很熟悉了,使用了插件的方式读取init
配置,有兴趣的可以看看源码
此时再回到BuildScriptProcessor#execute
public void execute(final ProjectInternal project) {
// ...
try {
final ScriptPlugin configurer = configurerFactory.create(project.getBuildScriptSource(), project.getBuildscript(), project.getClassLoaderScope(), project.getBaseClassLoaderScope(), true);
project.getMutationState().applyToMutableState(configurer::apply);
} finally {
// ...
}
}
此处是解析build.gradle
文件
3.5.3 TaskGraph阶段
//DefaultGradleLauncher#prepareTaskExecution
private void prepareTaskExecution() {
if (stage == Stage.Configure) {
taskExecutionPreparer.prepareForTaskExecution(gradle);
stage = Stage.TaskGraph;
}
}
taskExecutionPreparer
是TaskExecutionPreparer taskExecutionPreparer = gradle.getServices().get(TaskExecutionPreparer.class);
// GradleScopeServices#createTaskExecutionPreparer
TaskExecutionPreparer createTaskExecutionPreparer(BuildConfigurationActionExecuter buildConfigurationActionExecuter, IncludedBuildControllers includedBuildControllers, BuildOperationExecutor buildOperationExecutor) {
return new BuildOperationFiringTaskExecutionPreparer(
new DefaultTaskExecutionPreparer(buildConfigurationActionExecuter, includedBuildControllers, buildOperationExecutor),
buildOperationExecutor);
}
// DefaultTaskExecutionPreparer#prepareForTaskExecution
public void prepareForTaskExecution(GradleInternal gradle) {
buildConfigurationActionExecuter.select(gradle);
TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();
taskGraph.populate();
includedBuildControllers.populateTaskGraphs();
if (gradle.getStartParameter().isConfigureOnDemand()) {
new ProjectsEvaluatedNotifier(buildOperationExecutor).notify(gradle);
}
}
// buildConfigurationActionExecuter.select BuildConfigurationActionExecuter获取
BuildConfigurationActionExecuter createBuildConfigurationActionExecuter(CommandLineTaskParser commandLineTaskParser, TaskSelector taskSelector, ProjectConfigurer projectConfigurer, ProjectStateRegistry projectStateRegistry) {
List<BuildConfigurationAction> taskSelectionActions = new LinkedList<BuildConfigurationAction>();
taskSelectionActions.add(new DefaultTasksBuildExecutionAction(projectConfigurer));
taskSelectionActions.add(new TaskNameResolvingBuildConfigurationAction(commandLineTaskParser));
return new DefaultBuildConfigurationActionExecuter(Arrays.asList(new ExcludedTaskFilteringBuildConfigurationAction(taskSelector)), taskSelectionActions, projectStateRegistry);
}
// ExcludedTaskFilteringBuildConfigurationAction排除某些Task
public void configure(BuildExecutionContext context) {
GradleInternal gradle = context.getGradle();
Set<String> excludedTaskNames = gradle.getStartParameter().getExcludedTaskNames();
if (!excludedTaskNames.isEmpty()) {
final Set<Spec<Task>> filters = new HashSet<Spec<Task>>();
for (String taskName : excludedTaskNames) {
filters.add(taskSelector.getFilter(taskName));
}
gradle.getTaskGraph().useFilter(Specs.intersect(filters));
}
context.proceed();
}
// DefaultTasksBuildExecutionAction构建默认的Task
public void configure(BuildExecutionContext context) {
StartParameter startParameter = context.getGradle().getStartParameter();
for (TaskExecutionRequest request : startParameter.getTaskRequests()) {
if (!request.getArgs().isEmpty()) {
context.proceed();
return;
}
}
// Gather the default tasks from this first group project
ProjectInternal project = context.getGradle().getDefaultProject();
//so that we don't miss out default tasks
projectConfigurer.configure(project);
List<String> defaultTasks = project.getDefaultTasks();
if (defaultTasks.size() == 0) {
defaultTasks = Collections.singletonList(ProjectInternal.HELP_TASK);
LOGGER.info("No tasks specified. Using default task {}", GUtil.toString(defaultTasks));
} else {
LOGGER.info("No tasks specified. Using project default tasks {}", GUtil.toString(defaultTasks));
}
startParameter.setTaskNames(defaultTasks);
context.proceed();
}
// TaskNameResolvingBuildConfigurationAction#configure 生成任务执行图
public void configure(BuildExecutionContext context) {
GradleInternal gradle = context.getGradle();
TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();
List<TaskExecutionRequest> taskParameters = gradle.getStartParameter().getTaskRequests();
for (TaskExecutionRequest taskParameter : taskParameters) {
List<TaskSelection> taskSelections = commandLineTaskParser.parseTasks(taskParameter);
for (TaskSelection taskSelection : taskSelections) {
LOGGER.info("Selected primary task '{}' from project {}", taskSelection.getTaskName(), taskSelection.getProjectPath());
taskGraph.addEntryTasks(taskSelection.getTasks());
}
}
context.proceed();
}
// DefaultTaskExecutionGraph#addEntryTasks
public void addEntryTasks(Iterable<? extends Task> tasks) {
assert tasks != null;
final Timer clock = Time.startTimer();
Set<Task> taskSet = new LinkedHashSet<>();
for (Task task : tasks) {
taskSet.add(task);
requestedTasks.add(task);
}
executionPlan.addEntryTasks(taskSet);
graphState = GraphState.DIRTY;
LOGGER.debug("Timing: Creating the DAG took " + clock.getElapsed());
}
// DefaultExecutionPlan#addEntryTasks
public void addEntryTasks(Collection<? extends Task> tasks) {
final Deque<Node> queue = new ArrayDeque<>();
for (Task task : sorted(tasks)) {
TaskNode node = taskNodeFactory.getOrCreateNode(task);
if (node.isMustNotRun()) {
requireWithDependencies(node);
} else if (filter.isSatisfiedBy(task)) {
node.require();
}
entryNodes.add(node);
queue.add(node);
}
doAddNodes(queue);
}
此时Task
都创建好了,并且都加入到了executionPlan
,此时再回到DefaultTaskExecutionPreparer#prepareForTaskExecution
public void prepareForTaskExecution(GradleInternal gradle) {
buildConfigurationActionExecuter.select(gradle);
TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();
taskGraph.populate();
includedBuildControllers.populateTaskGraphs();
if (gradle.getStartParameter().isConfigureOnDemand()) {
new ProjectsEvaluatedNotifier(buildOperationExecutor).notify(gradle);
}
}
taskGraph.populate()
最终调用到DefaultExecutionPlan#determineExecutionPlan
构建任务执行图
小结:
DefaultGradleLauncher#prepareTaskExecution
构建Task开始DefaultTaskExecutionPreparer#prepareForTaskExecution
构建执行ExcludedTaskFilteringBuildConfigurationAction
排除某些TaskDefaultTasksBuildExecutionAction
创建默认TaskTaskNameResolvingBuildConfigurationAction
把创建好的Task
存储到DefaultExecutionPlan
DefaultTaskExecutionPreparer#prepareForTaskExecution -> taskGraph.populate() -> DefaultExecutionPlan#determineExecutionPlan
构建Task执行图
3.5.4 RunTasks阶段
// DefaultGradleLauncher#runWork
private void runWork() {
List<Throwable> taskFailures = new ArrayList<>();
buildExecuter.execute(gradle, taskFailures);
stage = Stage.RunTasks;
}
// buildExecuter = gradle.getServices().get(BuildWorkExecutor.class)
// GradleScopeServices#createBuildExecuter
BuildWorkExecutor createBuildExecuter(StyledTextOutputFactory textOutputFactory, IncludedBuildControllers includedBuildControllers, BuildOperationExecutor buildOperationExecutor) {
return new BuildOperationFiringBuildWorkerExecutor(
new DeprecateUndefinedBuildWorkExecutor(
new IncludedBuildLifecycleBuildWorkExecutor(
new DefaultBuildWorkExecutor(
asList(new DryRunBuildExecutionAction(textOutputFactory),
new SelectedTaskExecutionAction())),
includedBuildControllers)),
buildOperationExecutor);
}
// SelectedTaskExecutionAction#execute
public void execute(BuildExecutionContext context, Collection<? super Throwable> taskFailures) {
GradleInternal gradle = context.getGradle();
TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();
if (gradle.getStartParameter().isContinueOnFailure()) {
taskGraph.setContinueOnFailure(true);
}
bindAllReferencesOfProject(taskGraph);
taskGraph.execute(taskFailures);
}
//DefaultTaskExecutionGraph#execute -> executeWithServices
private void executeWithServices(ProjectExecutionServiceRegistry projectExecutionServices, Collection<? super Throwable> failures) {
Timer clock = Time.startTimer();
try {
planExecutor.process(
executionPlan,
failures,
new BuildOperationAwareExecutionAction(
buildOperationExecutor.getCurrentOperation(),
new InvokeNodeExecutorsAction(nodeExecutors, projectExecutionServices)
)
);
LOGGER.debug("Timing: Executing the DAG took " + clock.getElapsed());
} finally {
coordinationService.withStateLock(resourceLockState -> {
executionPlan.clear();
return ResourceLockState.Disposition.FINISHED;
});
}
}
// DefaultPlanExecutor#process
public void process(ExecutionPlan executionPlan, Collection<? super Throwable> failures, Action<Node> nodeExecutor) {
ManagedExecutor executor = executorFactory.create("Execution worker for '" + executionPlan.getDisplayName() + "'");
try {
WorkerLease parentWorkerLease = workerLeaseService.getCurrentWorkerLease();
startAdditionalWorkers(executionPlan, nodeExecutor, executor, parentWorkerLease);
new ExecutorWorker(executionPlan, nodeExecutor, parentWorkerLease, cancellationToken, coordinationService).run();
awaitCompletion(executionPlan, failures);
} finally {
executor.stop();
}
}
// DefaultPlanExecutor.ExecutorWorker#run
public void run() {
final AtomicLong busy = new AtomicLong(0);
Timer totalTimer = Time.startTimer();
final Timer executionTimer = Time.startTimer();
WorkerLease childLease = parentWorkerLease.createChild();
while (true) {
boolean nodesRemaining = executeNextNode(childLease, work -> {
LOGGER.info("{} ({}) started.", work, Thread.currentThread());
executionTimer.reset();
nodeExecutor.execute(work);
long duration = executionTimer.getElapsedMillis();
busy.addAndGet(duration);
if (LOGGER.isInfoEnabled()) {
LOGGER.info("{} ({}) completed. Took {}.", work, Thread.currentThread(), TimeFormatting.formatDurationVerbose(duration));
}
});
if (!nodesRemaining) {
break;
}
}
long total = totalTimer.getElapsedMillis();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Execution worker [{}] finished, busy: {}, idle: {}", Thread.currentThread(), TimeFormatting.formatDurationVerbose(busy.get()), TimeFormatting.formatDurationVerbose(total - busy.get()));
}
}
nodeExecutor
创建
// ProjectExecutionServices#createTaskExecuter
TaskExecuter createTaskExecuter(...) {
TaskExecuter executer = new ExecuteActionsTaskExecuter(
buildCacheController.isEnabled()
? ExecuteActionsTaskExecuter.BuildCacheState.ENABLED
: ExecuteActionsTaskExecuter.BuildCacheState.DISABLED,
gradleEnterprisePluginManager.isPresent()
? ExecuteActionsTaskExecuter.ScanPluginState.APPLIED
: ExecuteActionsTaskExecuter.ScanPluginState.NOT_APPLIED,
executionHistoryStore,
buildOperationExecutor,
asyncWorkTracker,
actionListener,
taskCacheabilityResolver,
fingerprinterRegistry,
classLoaderHierarchyHasher,
executionEngine,
listenerManager,
reservedFileSystemLocationRegistry,
emptySourceTaskSkipper,
fileCollectionFactory,
fileOperations
);
executer = new CleanupStaleOutputsExecuter(
buildOperationExecutor,
cleanupRegistry,
deleter,
outputChangeListener,
outputFilesRepository,
executer
);
executer = new FinalizePropertiesTaskExecuter(executer);
executer = new ResolveTaskExecutionModeExecuter(repository, fileCollectionFactory, propertyWalker, executer);
executer = new SkipTaskWithNoActionsExecuter(taskExecutionGraph, executer);
executer = new SkipOnlyIfTaskExecuter(executer);
executer = new CatchExceptionTaskExecuter(executer);
executer = new EventFiringTaskExecuter(buildOperationExecutor, taskExecutionListener, taskListenerInternal, executer);
return executer;
}
EventFiringTaskExecuter
: 通知任务开始事件CatchExceptionTaskExecuter
: 加上try-catch
异常捕获SkipOnlyIfTaskExecuter
: 判断Task
执行条件是否满足SkipTaskWithNoActionsExecuter
: 跳过没有action
的Task
ResolveTaskExecutionModeExecuter
: 解析Task
的信息FinalizePropertiesTaskExecuter
: 通知任务开始和结束CleanupStaleOutputsExecuter
: 任务执行前清除之前输出的产物ExecuteActionsTaskExecuter
: 真正执行Task
// EventFiringTaskExecuter#execute
public TaskExecuterResult execute(TaskInternal task, TaskStateInternal state, TaskExecutionContext context) {
TaskExecution work = new TaskExecution(task, context, executionHistoryStore, fingerprinterRegistry, classLoaderHierarchyHasher);
try {
return executeIfValid(task, state, context, work);
} catch (WorkValidationException ex) {
state.setOutcome(ex);
return TaskExecuterResult.WITHOUT_OUTPUTS;
}
}
// TaskExecution#execute
@Override
public WorkOutput execute(@Nullable InputChangesInternal inputChanges, InputChangesContext context) {
FileCollection previousFiles = context.getAfterPreviousExecutionState()
.map(afterPreviousExecutionState -> (FileCollection) new PreviousOutputFileCollection(task, afterPreviousExecutionState))
.orElseGet(fileCollectionFactory::empty);
TaskOutputsInternal outputs = task.getOutputs();
outputs.setPreviousOutputFiles(previousFiles);
try {
WorkResult didWork = executeWithPreviousOutputFiles(inputChanges);
return new WorkOutput() {
@Override
public WorkResult getDidWork() {
return didWork;
}
@Override
public Object getOutput() {
throw new UnsupportedOperationException();
}
};
} finally {
outputs.setPreviousOutputFiles(null);
}
}
private WorkResult executeWithPreviousOutputFiles(@Nullable InputChangesInternal inputChanges) {
task.getState().setExecuting(true);
try {
LOGGER.debug("Executing actions for {}.", task);
actionListener.beforeActions(task);
executeActions(task, inputChanges);
return task.getState().getDidWork() ? WorkResult.DID_WORK : WorkResult.DID_NO_WORK;
} finally {
task.getState().setExecuting(false);
actionListener.afterActions(task);
}
}
private void executeActions(TaskInternal task, @Nullable InputChangesInternal inputChanges) {
boolean hasTaskListener = listenerManager.hasListeners(TaskActionListener.class) || listenerManager.hasListeners(TaskExecutionListener.class);
Iterator<InputChangesAwareTaskAction> actions = new ArrayList<>(task.getTaskActions()).iterator();
while (actions.hasNext()) {
InputChangesAwareTaskAction action = actions.next();
task.getState().setDidWork(true);
task.getStandardOutputCapture().start();
boolean hasMoreWork = hasTaskListener || actions.hasNext();
try {
executeAction(action.getDisplayName(), task, action, inputChanges, hasMoreWork);
} catch (StopActionException e) {
// Ignore
LOGGER.debug("Action stopped by some action with message: {}", e.getMessage());
} catch (StopExecutionException e) {
LOGGER.info("Execution stopped by some action with message: {}", e.getMessage());
break;
} finally {
task.getStandardOutputCapture().stop();
}
}
}
private void executeAction(String actionDisplayName, TaskInternal task, InputChangesAwareTaskAction action, @Nullable InputChangesInternal inputChanges, boolean hasMoreWork) {
if (inputChanges != null) {
action.setInputChanges(inputChanges);
}
buildOperationExecutor.run(new RunnableBuildOperation() {
// ...
}
@Override
public void run(BuildOperationContext context) {
try {
BuildOperationRef currentOperation = buildOperationExecutor.getCurrentOperation();
Throwable actionFailure = null;
try {
action.execute(task);
} catch (Throwable t) {
actionFailure = t;
} finally {
action.clearInputChanges();
}
}
// ...
}
}
此处开始执行Task
3.5.5 Finished阶段
DefaultGradleLauncher#finishBuild
private void finishBuild(String action, @Nullable Throwable stageFailure) {
if (stage == Stage.Finished) {
return;
}
RuntimeException reportableFailure = stageFailure == null ? null : exceptionAnalyser.transform(stageFailure);
BuildResult buildResult = new BuildResult(action, gradle, reportableFailure);
List<Throwable> failures = new ArrayList<>();
includedBuildControllers.finishBuild(failures);
try {
buildListener.buildFinished(buildResult);
buildFinishedListener.buildFinished((GradleInternal) buildResult.getGradle());
} catch (Throwable t) {
failures.add(t);
}
stage = Stage.Finished;
if (failures.isEmpty() && reportableFailure != null) {
throw reportableFailure;
}
if (!failures.isEmpty()) {
if (stageFailure instanceof MultipleBuildFailures) {
failures.addAll(0, ((MultipleBuildFailures) stageFailure).getCauses());
} else if (stageFailure != null) {
failures.add(0, stageFailure);
}
throw exceptionAnalyser.transform(new MultipleBuildFailures(failures));
}
}
这里就是生命周期回调
至此,任务的创建到执行过程基本跟踪完成了,主要以下几个步骤
- 解析
setting.gradle
文件,并生成Project
实例对象 - 解析
build.gradle
并执行 - 创建并生成
Task
执行图 - 执行
Task
4. 总结
虽然中间逻辑很复杂,面向接口的编程,通过接口类型反射匹配从众多service中找到对应的调用方法,代码跟进难度大,但是好在最终还是慢慢摸清了套路。虽然过程不一定完全正确,但是大致的脉络应该没差。至此,开篇的几个问题终归有了解答。
4.1 学到的东西
4.1.1 面向接口,一些对象的获取,通过service提供
例如:ProjectsPreparer projectsPreparer = serviceRegistry.get(ProjectsPreparer.class)
通过解析ProjectsPreparer.class
的类型,从注册的服务树依次匹配,服务BuildScopeServices
获取,
protected ProjectsPreparer createBuildConfigurer() {
// ...
}
4.1.2 装饰模式
protected ProjectsPreparer createBuildConfigurer(ProjectConfigurer projectConfigurer, BuildSourceBuilder buildSourceBuilder, BuildStateRegistry buildStateRegistry, BuildLoader buildLoader, ListenerManager listenerManager, BuildOperationExecutor buildOperationExecutor) {
ModelConfigurationListener modelConfigurationListener = listenerManager.getBroadcaster(ModelConfigurationListener.class);
return new BuildOperationFiringProjectsPreparer(
new BuildTreePreparingProjectsPreparer(
new DefaultProjectsPreparer(
projectConfigurer,
modelConfigurationListener,
buildOperationExecutor),
buildLoader,
buildStateRegistry,
buildSourceBuilder),
buildOperationExecutor);
}
以这个为例,都是实现了ProjectsPreparer
接口,然后构造体传入其他的ProjectsPreparer
,为其增加不同的功能
4.1.3 外观模式
gradle wrapper
封装了不同gradle
版本的调用细节,对外提供统一的调用接口,而无需关注gradle
的版本变化。