aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLexManos <LexManos@gmail.com>2019-05-03 15:43:07 -0700
committerGitHub <noreply@github.com>2019-05-03 15:43:07 -0700
commitd3c01e7be2247cce9f6fe3456db73dd0a7ef1ccf (patch)
tree945e46af6d7359a987d31a30c162bc167e741407
parent37d713bdb7459cdd44707b350fd12fd59517b415 (diff)
parent747c582804bdcd0409417fdd92f7a3042d80b6b5 (diff)
downloadArtifactural-d3c01e7be2247cce9f6fe3456db73dd0a7ef1ccf.tar.gz
Artifactural-d3c01e7be2247cce9f6fe3456db73dd0a7ef1ccf.tar.bz2
Artifactural-d3c01e7be2247cce9f6fe3456db73dd0a7ef1ccf.zip
Merge pull request #1 from Aaron1011/gradle-compat-final
Add compatibility with Gradle 4.10 and above
-rw-r--r--build.gradle158
-rw-r--r--gradle.properties1
-rw-r--r--gradle/wrapper/gradle-wrapper.jarbin52271 -> 54413 bytes
-rw-r--r--gradle/wrapper/gradle-wrapper.properties4
-rwxr-xr-xgradlew78
-rw-r--r--gradlew.bat174
-rw-r--r--src/gradlecomp/java/com/amadornes/artifactural/gradle/Gradle410RepositoryAdapter.java42
-rw-r--r--src/gradlecomp/java/com/amadornes/artifactural/gradle/GradleRepositoryAdapter.java54
8 files changed, 381 insertions, 130 deletions
diff --git a/build.gradle b/build.gradle
index 635950d..d6cbd04 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,9 +1,30 @@
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ // Needed for bytecode manipulation
+ classpath 'org.ow2.asm:asm-all:5.2'
+ }
+}
+
plugins {
id 'net.minecrell.licenser' version '0.3'
id 'org.ajoberstar.grgit' version '2.3.0'
//id 'com.github.johnrengelman.shadow' version '2.0.4'
}
+import java.nio.file.Paths
+import org.objectweb.asm.ClassReader
+import org.objectweb.asm.ClassWriter
+import org.objectweb.asm.Opcodes
+import org.objectweb.asm.tree.ClassNode
+import org.objectweb.asm.tree.MethodInsnNode
+import org.objectweb.asm.tree.VarInsnNode
+import org.objectweb.asm.tree.InsnNode
+
+import java.util.jar.JarFile
+
apply plugin: 'java'
apply plugin: 'maven-publish'
@@ -15,7 +36,7 @@ def gitVersion() {
def hash = desc.remove(desc.size() - 1)
def offset = desc.remove(desc.size() - 1)
def tag = desc.join('-')
- def branch = grgit.branch.current().name
+ def branch = grgit.branch.current().name
return "${tag}.${offset}" //${t -> if (branch != 'master') t << '-' + branch}"
}
@@ -52,10 +73,143 @@ dependencies {
compile sourceSets.gradlecomp.output
}
+
+
+def gradleRepositoryAdapterPath = Paths.get("com", "amadornes", "artifactural", "gradle", "GradleRepositoryAdapter.class")
+def classesDirs = sourceSets.gradlecomp.output.classesDirs.getFiles().first().toPath()
+
+
+def _constructorName = "<init>"
+def _constructorDesc = "(Lcom/amadornes/artifactural/api/repository/Repository;Lorg/gradle/api/internal/artifacts/repositories/DefaultMavenLocalArtifactRepository;)V"
+def _modifiedSuperDesc = "()V"
+
+// This task patches 'GradleRepositoryAdapter' to make it compatibile with both Gradle 4.9 and 4.10
+// In Gradle 4.9, the constructor of AbstractArtifactRepository changes has zero arguments
+// (instead of the one-argument constructor in 4.10, which we compile against)
+// It's not possible to write a normal Java class that calls a constructor which doesn't exist at compile time.
+// Therefore, we need to patch the bytecode of the class to properly call the non-arg super() constrcutor
+class PatchGradleRepositoryAdapter extends DefaultTask {
+
+ @Input String constructorName
+ @Input String constructorDesc
+ @Input String modifiedSuperDesc
+ @Input File gradleRepositoryAdapter
+ @Input File classesDir
+ @OutputDirectory java.nio.file.Path outputDir
+
+
+ @TaskAction
+ void patchClass() {
+ def originalGradleRepositoryAdapter = Paths.get(classesDir.toString(), gradleRepositoryAdapter.toString())
+
+ ClassNode node = new ClassNode()
+ ClassReader reader = new ClassReader(new FileInputStream(originalGradleRepositoryAdapter.toFile()))
+ reader.accept(node, 0)
+
+
+ def constructor = node.methods.find {
+ it.name == constructorName && it.desc == constructorDesc
+ }
+
+ def getDescriptor = node.methods.find {
+ it.name == "getDescriptor"
+ }
+
+ if (constructor == null) {
+ throw new RuntimeException("Failed to find target constructor!")
+ }
+
+ if (getDescriptor == null) {
+ throw new RuntimeException("Failed to find getDescriptor()")
+ }
+
+ // Strip out this method - it only exists
+ // so that GradleRepositoryAdapter will compile
+ node.methods.remove(getDescriptor)
+
+ def superInvoc = constructor.instructions.find {
+ it instanceof MethodInsnNode && it.owner == "org/gradle/api/internal/artifacts/repositories/AbstractArtifactRepository"
+ } as MethodInsnNode
+
+ if (superInvoc == null) {
+ throw new RuntimeException("Failed to find target super() invocation!")
+ }
+
+ superInvoc.desc = modifiedSuperDesc
+
+ def aconstNull = superInvoc.previous
+ if (!(aconstNull instanceof InsnNode) || aconstNull.type != 0) {
+ throw new RuntimeException("Unexpected instruction: " + aconstNull)
+ }
+
+ constructor.instructions.remove(aconstNull)
+
+ // Push first parameter of constructor (the ObjectFactory) onto the stack.
+ // This has the effect of calling super(objectFactory)
+ //constructor.instructions.insertBefore(superInvoc, new VarInsnNode(Opcodes.ALOAD, 1))
+
+ ClassWriter writer = new ClassWriter(0)
+ node.accept(writer)
+
+ def outputFile = outputDir.resolve(gradleRepositoryAdapter.toPath()).toFile()
+
+ outputFile.parentFile.mkdirs()
+ FileOutputStream fs = new FileOutputStream(outputFile)
+ fs.write(writer.toByteArray())
+ }
+}
+
+
+
+task patchConstructor(type: PatchGradleRepositoryAdapter) {
+ constructorName = _constructorName
+ constructorDesc = _constructorDesc
+ modifiedSuperDesc = _modifiedSuperDesc
+ classesDir = classesDirs.toFile()
+ outputDir = Paths.get(buildDir.toString(), "modifiedclasses")
+ gradleRepositoryAdapter = gradleRepositoryAdapterPath.toFile()
+}
+
jar {
from sourceSets.api.output
from sourceSets.shared.output
- from sourceSets.gradlecomp.output
+ from(sourceSets.gradlecomp.output) {
+ exclude gradleRepositoryAdapterPath.toString()
+ }
+
+ from patchConstructor.outputs
+}
+
+jar.doLast {
+ def jarPath = it.outputs.files.getFiles().first()
+ def jarFile = new JarFile(jarPath)
+ def entry = jarFile.getEntry(gradleRepositoryAdapterPath.toString())
+ def stream = jarFile.getInputStream(entry)
+
+ ClassReader reader = new ClassReader(stream)
+ ClassNode node = new ClassNode()
+ reader.accept(node, 0)
+
+ def constructor = node.methods.find {
+ it.name == _constructorName && it.desc == _constructorDesc
+ }
+
+ def superInvoc = constructor.instructions.find {
+ it instanceof MethodInsnNode && it.owner == "org/gradle/api/internal/artifacts/repositories/AbstractArtifactRepository"
+ } as MethodInsnNode
+
+ if (superInvoc.desc == _modifiedSuperDesc) {
+ println("Successfully modified super() call!")
+ } else {
+ throw new RuntimeException("Failed to modify super() invocation - got desc of " + superInvoc.desc)
+ }
+
+ def getDescriptor = node.methods.find { it.name == "getDescriptor"}
+ if (getDescriptor != null) {
+ throw new RuntimeException("Failed to remove getDescriptor with signature: " + getDescriptor.signature)
+ } else {
+ println("Successfully stripped getDescriptor method!")
+ }
}
task sourcesJar(type: Jar, dependsOn: classes) {
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1 @@
+
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 30d399d..0d4a951 100644
--- a/gradle/wrapper/gradle-wrapper.jar
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 5aa013a..2e7105d 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sat Jun 09 16:26:43 CEST 2018
+#Thu Apr 25 19:18:54 EDT 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip
diff --git a/gradlew b/gradlew
index 91a7e26..cccdd3d 100755
--- a/gradlew
+++ b/gradlew
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
##############################################################################
##
@@ -6,20 +6,38 @@
##
##############################################################################
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
-warn ( ) {
+warn () {
echo "$*"
}
-die ( ) {
+die () {
echo
echo "$*"
echo
@@ -30,6 +48,7 @@ die ( ) {
cygwin=false
msys=false
darwin=false
+nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
@@ -40,31 +59,11 @@ case "`uname`" in
MINGW* )
msys=true
;;
+ NONSTOP* )
+ nonstop=true
+ ;;
esac
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -90,7 +89,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -114,6 +113,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@@ -154,11 +154,19 @@ if $cygwin ; then
esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index 8a0b282..e95643d 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -1,90 +1,84 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windowz variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/src/gradlecomp/java/com/amadornes/artifactural/gradle/Gradle410RepositoryAdapter.java b/src/gradlecomp/java/com/amadornes/artifactural/gradle/Gradle410RepositoryAdapter.java
new file mode 100644
index 0000000..ceaf989
--- /dev/null
+++ b/src/gradlecomp/java/com/amadornes/artifactural/gradle/Gradle410RepositoryAdapter.java
@@ -0,0 +1,42 @@
+/*
+ * Artifactural
+ * Copyright (c) 2018.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package com.amadornes.artifactural.gradle;
+
+import com.amadornes.artifactural.api.repository.Repository;
+import org.gradle.api.internal.artifacts.repositories.DefaultMavenLocalArtifactRepository;
+import org.gradle.api.internal.artifacts.repositories.descriptor.FlatDirRepositoryDescriptor;
+import org.gradle.api.internal.artifacts.repositories.descriptor.RepositoryDescriptor;
+import org.gradle.api.model.ObjectFactory;
+
+import java.util.ArrayList;
+
+public class Gradle410RepositoryAdapter extends GradleRepositoryAdapter {
+
+ Gradle410RepositoryAdapter(ObjectFactory objectFactory, Repository repository, DefaultMavenLocalArtifactRepository local) {
+ super(objectFactory, repository, local);
+ }
+
+
+ @Override
+ public RepositoryDescriptor getDescriptor() {
+ return new FlatDirRepositoryDescriptor("ArtifacturalRepository", new ArrayList<>());
+ }
+
+}
diff --git a/src/gradlecomp/java/com/amadornes/artifactural/gradle/GradleRepositoryAdapter.java b/src/gradlecomp/java/com/amadornes/artifactural/gradle/GradleRepositoryAdapter.java
index 64d6652..669ad4c 100644
--- a/src/gradlecomp/java/com/amadornes/artifactural/gradle/GradleRepositoryAdapter.java
+++ b/src/gradlecomp/java/com/amadornes/artifactural/gradle/GradleRepositoryAdapter.java
@@ -37,11 +37,14 @@ import org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.Resol
import org.gradle.api.internal.artifacts.repositories.AbstractArtifactRepository;
import org.gradle.api.internal.artifacts.repositories.DefaultMavenLocalArtifactRepository;
import org.gradle.api.internal.artifacts.repositories.ResolutionAwareRepository;
+import org.gradle.api.internal.artifacts.repositories.descriptor.FlatDirRepositoryDescriptor;
+import org.gradle.api.internal.artifacts.repositories.descriptor.RepositoryDescriptor;
import org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceArtifactResolver;
import org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver;
import org.gradle.api.internal.artifacts.repositories.resolver.MavenResolver;
import org.gradle.api.internal.artifacts.repositories.resolver.MetadataFetchingCost;
import org.gradle.api.internal.component.ArtifactType;
+import org.gradle.api.model.ObjectFactory;
import org.gradle.internal.action.InstantiatingAction;
import org.gradle.internal.component.external.model.ModuleComponentResolveMetadata;
import org.gradle.internal.component.external.model.ModuleDependencyMetadata;
@@ -65,10 +68,12 @@ import org.gradle.internal.resource.local.LocalFileStandInExternalResource;
import org.gradle.internal.resource.local.LocallyAvailableExternalResource;
import org.gradle.internal.resource.metadata.ExternalResourceMetaData;
import org.gradle.internal.resource.transfer.DefaultCacheAwareExternalResourceAccessor;
+import org.gradle.util.GradleVersion;
import java.io.File;
import java.io.IOException;
import java.net.URI;
+import java.util.ArrayList;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -85,7 +90,18 @@ public class GradleRepositoryAdapter extends AbstractArtifactRepository implemen
maven.setUrl(local);
maven.setName(name);
- GradleRepositoryAdapter repo = new GradleRepositoryAdapter(repository, maven);
+ GradleRepositoryAdapter repo;
+
+ // On Gradle 4.10 above, we need to use the constructor with the 'ObjectFactory' parameter
+ // (which can be safely passed as null - see BaseMavenInstaller).
+ // We use Gradle410RepositoryAdapter, which actually overrides 'getDescriptor'
+ if (GradleVersion.current().compareTo(GradleVersion.version("4.10")) >= 0) {
+ repo = new Gradle410RepositoryAdapter(null, repository, maven);
+ } else {
+ // On versions of gradle older than 4.10, we use the no-arg super constructor
+ repo = new GradleRepositoryAdapter(repository, maven);
+ }
+
repo.setName(name);
handler.add(repo);
return repo;
@@ -96,7 +112,25 @@ public class GradleRepositoryAdapter extends AbstractArtifactRepository implemen
private final String root;
private final LocatedArtifactCache cache;
+
+ // This constructor is modified via bytecode manipulation in 'build.gradle'
+ // DO NOT change this without modifying 'build.gradle'
+ // This contructor is used on Gradle 4.9 and below
private GradleRepositoryAdapter(Repository repository, DefaultMavenLocalArtifactRepository local) {
+ // This is replaced with a call to 'super()', with no arguments
+ super(null);
+ this.repository = repository;
+ this.local = local;
+ this.root = cleanRoot(local.getUrl());
+ this.cache = new LocatedArtifactCache(new File(root));
+ }
+
+
+ // This constructor is used on Gradle 4.10 and above
+ GradleRepositoryAdapter(ObjectFactory objectFactory, Repository repository, DefaultMavenLocalArtifactRepository local) {
+ super(objectFactory);
+ // This duplication from the above two-argument constructor is unfortunate,
+ // but unavoidable
this.repository = repository;
this.local = local;
this.root = cleanRoot(local.getUrl());
@@ -182,6 +216,24 @@ public class GradleRepositoryAdapter extends AbstractArtifactRepository implemen
};
}
+ // This method will be deleted entirely in build.gradle
+ // In order for this class to compile, this method needs to exist
+ // at compile-time. However, the class 'RepositoryDescriptor' doesn't
+ // exist in Gradle 4.9. If we try to classload a class
+ // that contains RepositoryDescriptor as a method return type,
+ // the JVM will try to classload RepositoryDescriptor, leading
+ // to a NoClassDefFoundError
+
+ // To fix this, we strip out this method at build time.
+ // At runtime, we instantiate Gradle410RepositoryAdapter
+ // when we're running on Gradle 4.10 on above.
+ // This ensures that 'getDescriptor' exists on Gradle 4.10,
+ // and doesn't existon Gradle 4.9
+ public RepositoryDescriptor getDescriptor() {
+ throw new Error("This method should be been stripped at build time!");
+ }
+
+
private static String cleanRoot(URI uri) {
String ret = uri.normalize().getPath().replace('\\', '/');
if (!ret.endsWith("/")) ret += '/';