Skip to content

Commit

Permalink
* Fix compatibility with Gradle 8.x (pull #31)
Browse files Browse the repository at this point in the history
  • Loading branch information
milkyway0308 authored Oct 22, 2023
1 parent 849a4c9 commit 4ddf762
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 34 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

* Fix compatibility with Gradle 8.x ([pull #31](https://github.com/bytedeco/gradle-javacpp/issues/31))

### June 6, 2023 version 1.5.9
* Fix compatibility with Gradle 7.6.x ([issue #28](https://github.com/bytedeco/gradle-javacpp/issues/28))

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ To use Gradle JavaCPP, you will need to download and install the following softw
* OpenJDK http://openjdk.java.net/install/ or
* Oracle JDK http://www.oracle.com/technetwork/java/javase/downloads/ or
* IBM JDK http://www.ibm.com/developerworks/java/jdk/
* Gradle 5.0 or newer: https://gradle.org/releases/
* Gradle 6.0 or newer: https://gradle.org/releases/


Getting Started
Expand Down
25 changes: 3 additions & 22 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,25 +57,9 @@ javadoc {
'http://junit.org/junit4/javadoc/4.13.2']
}

//doesn't work with Gradle 5.x
//java {
// withJavadocJar()
// withSourcesJar()
//}

task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}

task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}

artifacts {
archives javadocJar
archives sourcesJar
java {
withJavadocJar()
withSourcesJar()
}

def pomClosure = {
Expand Down Expand Up @@ -117,8 +101,6 @@ publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact javadocJar
artifact sourcesJar
pom pomClosure
}
buildPluginMarkerMaven(MavenPublication) {
Expand Down Expand Up @@ -165,4 +147,3 @@ signing {
sign publishing.publications.platformPluginMarkerMaven
}
}

2 changes: 1 addition & 1 deletion samples/zlib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
}

group = 'org.bytedeco'
version = "1.2.13-$javacppVersion"
version = "1.3-$javacppVersion"

repositories {
mavenLocal()
Expand Down
4 changes: 2 additions & 2 deletions samples/zlib/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ set -e
mkdir -p build/$PLATFORM
cd build/$PLATFORM

ZLIB_VERSION=1.2.13
ZLIB_VERSION=1.3
if [[ ! -e "zlib-$ZLIB_VERSION.tar.gz" ]]; then
curl -L "http://zlib.net/zlib-$ZLIB_VERSION.tar.gz" -o "zlib-$ZLIB_VERSION.tar.gz"
fi
echo "b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30 zlib-$ZLIB_VERSION.tar.gz" | shasum -a 256 -c -
echo "ff0ba4c292013dbc27530b3a81e1f9a813cd39de01ca5e0f8bf355702efa593e zlib-$ZLIB_VERSION.tar.gz" | shasum -a 256 -c -

echo "Decompressing archives..."
tar --totals -xf "zlib-$ZLIB_VERSION.tar.gz"
Expand Down
30 changes: 29 additions & 1 deletion src/main/java/org/bytedeco/gradle/javacpp/BuildExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import groovy.util.Node;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
Expand All @@ -36,6 +37,8 @@
import org.gradle.api.artifacts.ResolvedArtifact;
import org.gradle.api.artifacts.ResolvedDependency;
import org.gradle.api.internal.project.DefaultProject;
import org.gradle.api.internal.tasks.DefaultTaskDependencyFactory;
import org.gradle.api.internal.tasks.TaskDependencyFactory;
import org.gradle.api.plugins.BasePluginConvention;
import org.gradle.api.publish.maven.MavenArtifact;
import org.gradle.api.publish.maven.MavenPom;
Expand All @@ -49,11 +52,35 @@
* @author Samuel Audet
*/
public class BuildExtension {
private static final Constructor<FileBasedMavenArtifact> compatibleArtifactConstructor;
private static final boolean isLegacy;
private final Logger logger = LoggerFactory.getLogger(BuildExtension.class);

BuildPlugin plugin;
Project project;

static {
boolean legacyCheck;
Constructor<FileBasedMavenArtifact> compatibleConstructor;
try {
// If gradle version is lower than 6.2, use legacy constructor.
compatibleConstructor = FileBasedMavenArtifact.class.getConstructor(File.class);
legacyCheck = true;
} catch (NoSuchMethodException e) {
try {
// If gradle version is equals or higher than 6.2, use latest constructor.
compatibleConstructor = FileBasedMavenArtifact.class.getConstructor(File.class, TaskDependencyFactory.class);
legacyCheck = false;
} catch (NoSuchMethodException e2) {
// If no compatible constructor found, constructor signature modified on latest version and do not compatible with this code.
// Throw exception to prevent build.
throw new RuntimeException("Could not find constructor for FileBasedMavenArtifact (Incompatible with this gradle version)", e);
}
}
isLegacy = legacyCheck;
compatibleArtifactConstructor = compatibleConstructor;
}

public BuildExtension(BuildPlugin plugin) {
this.plugin = plugin;
this.project = plugin.project;
Expand Down Expand Up @@ -88,7 +115,8 @@ public List<MavenArtifact> existingArtifacts(Configuration configuration) throws
File in = ra.getFile();
File out = new File(libsDir, in.getName());
Files.copy(in.toPath(), out.toPath(), StandardCopyOption.REPLACE_EXISTING);
MavenArtifact ma = new FileBasedMavenArtifact(out);
MavenArtifact ma = isLegacy ? compatibleArtifactConstructor.newInstance(out) :
compatibleArtifactConstructor.newInstance(out, DefaultTaskDependencyFactory.withNoAssociatedProject());
ma.setClassifier(ra.getClassifier());
artifacts.add(ma);
} catch (RuntimeException e) {
Expand Down
101 changes: 94 additions & 7 deletions src/main/java/org/bytedeco/gradle/javacpp/BuildPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Properties;
import java.util.Set;
import org.bytedeco.javacpp.Loader;
Expand All @@ -33,6 +36,7 @@
import org.gradle.api.file.FileTreeElement;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.provider.Property;
import org.gradle.api.specs.Spec;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskProvider;
Expand Down Expand Up @@ -89,6 +93,60 @@ boolean isLibraryPath(String path) {
return p != null && p.length() > 0 ? path.startsWith(p) : path.contains("/" + getPlatform() + getPlatformExtension() + "/");
}

private <T> void setProperty(String originalMethod, String propertyField, Object target, T value) {
Method method = findMethod(target.getClass(), originalMethod, value.getClass());
if (method != null) {
try {
invoke(method, target, value);
} catch (Exception e) {
throw new RuntimeException("Cannot set property " + method.getName() + " in " + target.getClass(), e);
}
} else {
Method propertyGetter = findMethod(target.getClass(), propertyField);
if (propertyGetter == null) {
throw new RuntimeException("Cannot find property getter method " + propertyField + " in " + target.getClass());
}
((Property<T>) invoke(propertyGetter, target)).set(value);
}
}

private <T> T getProperty(String originalMethod, String propertyMethod, Object target) {
Method method = findMethod(target.getClass(), originalMethod);
if (method != null) {
return (T) invoke(method, target);
}
Method propertyGetter = findMethod(target.getClass(), propertyMethod);
if (propertyGetter == null) {
throw new RuntimeException("Cannot find property getter method " + propertyMethod + " in " + target.getClass());
}
return ((Property<T>) invoke(propertyGetter, target)).get();
}

private Method findMethod(Class<?> cls, String methodName) {
for (Method method : cls.getMethods()) {
if (method.getName().equals(methodName)) {
return method;
}
}
return null;
}

private Method findMethod(Class<?> cls, String methodName, Class<?>... parameterTypes) {
try {
return cls.getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e) {
return null;
}
}

private <T> T invoke(Method method, Object target, Object... parameter) {
try {
return (T) method.invoke(target, parameter);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}

@Override public void apply(final Project project) {
this.project = project;
if (!project.hasProperty("javacppPlatform")) {
Expand Down Expand Up @@ -131,7 +189,16 @@ boolean isLibraryPath(String path) {
JavaCompile.class, new Action<JavaCompile>() { public void execute(JavaCompile task) {
task.setSource(main.getJava());
task.setClasspath(main.getCompileClasspath());
task.setDestinationDir(main.getJava().getOutputDir());
setProperty(
"setDestinationDir", // Deprecated in 7.1, will be removed in Gradle 9.0
"getDestinationDirectory", // Since 6.1
task,
getProperty(
"getOutputDir", // Deprecated in 7.1, removed in Gradle 8.0
"getClassesDirectory", // Since 6.1
main.getJava()
)
);
task.dependsOn("javacppBuildCommand");
}});

Expand Down Expand Up @@ -185,7 +252,11 @@ boolean isLibraryPath(String path) {
TaskProvider<Jar> javacppJarTask = project.getTasks().register("javacppJar",
Jar.class, new Action<Jar>() { public void execute(Jar task) {
task.from(main.getOutput());
task.setClassifier(getPlatform() + getPlatformExtension());
setProperty(
"setClassifier", // Deprecated in 7.0, removed in 8.0
"getArchiveClassifier", // Since 5.1
task,
getPlatform() + getPlatformExtension());
task.include(new Spec<FileTreeElement>() { public boolean isSatisfiedBy(FileTreeElement file) {
return file.isDirectory() || isLibraryPath(file.getPath());
}});
Expand All @@ -196,21 +267,37 @@ boolean isLibraryPath(String path) {

TaskProvider<Jar> javacppPlatformJarTask = project.getTasks().register("javacppPlatformJar",
Jar.class, new Action<Jar>() { public void execute(Jar task) {
task.setBaseName(project.getName() + "-platform");
setProperty(
"setBaseName", // Deprecated in 7.0, removed in 8.0
"getArchiveBaseName", // Since 5.1
task,
project.getName() + "-platform");
task.dependsOn("javacppJar");
}});

TaskProvider<Jar> javacppPlatformJavadocJarTask = project.getTasks().register("javacppPlatformJavadocJar",
Jar.class, new Action<Jar>() { public void execute(Jar task) {
task.setBaseName(project.getName() + "-platform");
task.setClassifier("javadoc");
setProperty(
"setBaseName", // Deprecated in 7.0, removed in 8.0
"getArchiveBaseName", // Since 5.1
task,
project.getName() + "-platform");
setProperty(
"setClassifier", // Deprecated in 7.0, removed in 8.0
"getArchiveClassifier", // Since 5.1
task,
"javadoc");
task.dependsOn("javacppPlatformJar");
}});

TaskProvider<Jar> javacppPlatformSourcesTask = project.getTasks().register("javacppPlatformSourcesJar",
Jar.class, new Action<Jar>() { public void execute(Jar task) {
task.setBaseName(project.getName() + "-platform");
task.setClassifier("sources");
setProperty(
"setBaseName", // Deprecated in 7.0, removed in 8.0
"getArchiveBaseName", // Since 5.1
task,
project.getName() + "-platform");
setProperty("setClassifier", "getArchiveClassifier", task, "sources");
task.dependsOn("javacppPlatformJar");
}});

Expand Down

0 comments on commit 4ddf762

Please sign in to comment.