diff --git a/src/IKVM.Maven.Sdk.Tasks.Java/ikvm-maven-sdk-tasks-java.pom b/src/IKVM.Maven.Sdk.Tasks.Java/ikvm-maven-sdk-tasks-java.pom index b663caf..6b76eda 100644 --- a/src/IKVM.Maven.Sdk.Tasks.Java/ikvm-maven-sdk-tasks-java.pom +++ b/src/IKVM.Maven.Sdk.Tasks.Java/ikvm-maven-sdk-tasks-java.pom @@ -10,52 +10,52 @@ org.apache.maven maven-model - 3.8.7 + 3.9.6 org.apache.maven maven-core - 3.8.7 + 3.9.6 org.apache.maven maven-resolver-provider - 3.8.7 + 3.9.6 org.apache.maven maven-settings-builder - 3.8.7 + 3.9.6 org.apache.maven.resolver maven-resolver-api - 1.6.3 + 1.9.18 org.apache.maven.resolver maven-resolver-spi - 1.6.3 + 1.9.18 org.apache.maven.resolver maven-resolver-impl - 1.6.3 + 1.9.18 org.apache.maven.resolver maven-resolver-connector-basic - 1.6.3 + 1.9.18 org.apache.maven.resolver maven-resolver-transport-file - 1.6.3 + 1.9.18 org.apache.maven.resolver maven-resolver-transport-http - 1.6.3 + 1.9.18 \ No newline at end of file diff --git a/src/IKVM.Maven.Sdk.Tasks.Tests/MavenReferenceItemResolveTests.cs b/src/IKVM.Maven.Sdk.Tasks.Tests/MavenReferenceItemResolveTests.cs index 774ea20..b779d88 100644 --- a/src/IKVM.Maven.Sdk.Tasks.Tests/MavenReferenceItemResolveTests.cs +++ b/src/IKVM.Maven.Sdk.Tasks.Tests/MavenReferenceItemResolveTests.cs @@ -572,6 +572,35 @@ public void CanResolveFromPrivateRepository() t.ResolvedReferences.Should().Contain(i => i.ItemSpec == "maven$org.apache.xmlgraphics:fop:2.8"); } + [TestMethod] + public void ExclusionsShouldExcludeSystemDependency() + { + var cacheFile = Path.GetTempFileName(); + + var engine = new Mock(); + var errors = new List(); + engine.Setup(x => x.LogErrorEvent(It.IsAny())).Callback((BuildErrorEventArgs e) => { errors.Add(e); TestContext.WriteLine("ERROR: " + e.Message); }); + engine.Setup(x => x.LogWarningEvent(It.IsAny())).Callback((BuildWarningEventArgs e) => TestContext.WriteLine("WARNING: " + e.Message)); + engine.Setup(x => x.LogMessageEvent(It.IsAny())).Callback((BuildMessageEventArgs e) => TestContext.WriteLine(e.Message)); + var t = new MavenReferenceItemResolve(); + t.BuildEngine = engine.Object; + t.CacheFile = cacheFile; + t.Repositories = new[] { GetCentralRepositoryItem() }; + + var i1 = new TaskItem("net.sf.jt400:jt400:20.0.6"); + i1.SetMetadata(MavenReferenceItemMetadata.GroupId, "net.sf.jt400"); + i1.SetMetadata(MavenReferenceItemMetadata.ArtifactId, "jt400"); + i1.SetMetadata(MavenReferenceItemMetadata.Version, "20.0.6"); + i1.SetMetadata(MavenReferenceItemMetadata.Exclusions, "com.sun:tools"); + + t.References = new[] { i1 }; + + t.Execute().Should().BeTrue(); + errors.Should().BeEmpty(); + + t.ResolvedReferences.Should().NotContain(i => i.ItemSpec == "maven$com.sun:tools:jar:1.8.0"); + } + } } diff --git a/src/IKVM.Maven.Sdk.Tasks/IKVM.Maven.Sdk.Tasks.csproj b/src/IKVM.Maven.Sdk.Tasks/IKVM.Maven.Sdk.Tasks.csproj index d0ae67a..ff0d3f7 100644 --- a/src/IKVM.Maven.Sdk.Tasks/IKVM.Maven.Sdk.Tasks.csproj +++ b/src/IKVM.Maven.Sdk.Tasks/IKVM.Maven.Sdk.Tasks.csproj @@ -9,6 +9,7 @@ + diff --git a/src/IKVM.Maven.Sdk.Tasks/Json/VersionConstraintJsonConverter.cs b/src/IKVM.Maven.Sdk.Tasks/Json/VersionConstraintJsonConverter.cs index bdb9321..4146739 100644 --- a/src/IKVM.Maven.Sdk.Tasks/Json/VersionConstraintJsonConverter.cs +++ b/src/IKVM.Maven.Sdk.Tasks/Json/VersionConstraintJsonConverter.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using System.Reflection; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; @@ -13,12 +15,20 @@ namespace IKVM.Maven.Sdk.Tasks.Json /// class VersionConstraintJsonConverter : JsonConverter { + + static readonly MethodInfo parseVersionConstraintMethod = typeof(GenericVersionScheme) + .GetMethods() + .Where(i => i.Name == "parseVersionConstraint") + .Where(i => i.GetParameters().Length == 1 && i.GetParameters()[0].ParameterType == typeof(string)) + .Where(i => i.ReturnType == typeof(GenericVersionScheme).Assembly.GetType("org.eclipse.aether.util.version.GenericVersionConstraint")) + .First(); + public override org.eclipse.aether.version.VersionConstraint Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.String) return null; else - return new GenericVersionScheme().parseVersionConstraint(reader.GetString()); + return (org.eclipse.aether.version.VersionConstraint)parseVersionConstraintMethod.Invoke(new GenericVersionScheme(), new[] { reader.GetString() }); } public override void Write(Utf8JsonWriter writer, org.eclipse.aether.version.VersionConstraint value, JsonSerializerOptions options) diff --git a/src/IKVM.Maven.Sdk.Tasks/Json/VersionJsonConverter.cs b/src/IKVM.Maven.Sdk.Tasks/Json/VersionJsonConverter.cs index 7206690..5ad2636 100644 --- a/src/IKVM.Maven.Sdk.Tasks/Json/VersionJsonConverter.cs +++ b/src/IKVM.Maven.Sdk.Tasks/Json/VersionJsonConverter.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using System.Reflection; using System.Text.Json; using System.Text.Json.Serialization; @@ -13,12 +15,19 @@ namespace IKVM.Maven.Sdk.Tasks.Json class VersionJsonConverter : JsonConverter { + static readonly MethodInfo parseVersionMethod = typeof(GenericVersionScheme) + .GetMethods() + .Where(i => i.Name == "parseVersion") + .Where(i => i.GetParameters().Length == 1 && i.GetParameters()[0].ParameterType == typeof(string)) + .Where(i => i.ReturnType == typeof(GenericVersionScheme).Assembly.GetType("org.eclipse.aether.util.version.GenericVersion")) + .First(); + public override org.eclipse.aether.version.Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.String) return null; else - return new GenericVersionScheme().parseVersion(reader.GetString()); + return (org.eclipse.aether.version.Version)parseVersionMethod.Invoke(new GenericVersionScheme(), new[] { reader.GetString() }); } public override void Write(Utf8JsonWriter writer, org.eclipse.aether.version.Version value, JsonSerializerOptions options) diff --git a/src/IKVM.Maven.Sdk.Tasks/MavenEnvironment.cs b/src/IKVM.Maven.Sdk.Tasks/MavenEnvironment.cs index 478d438..b67df9d 100644 --- a/src/IKVM.Maven.Sdk.Tasks/MavenEnvironment.cs +++ b/src/IKVM.Maven.Sdk.Tasks/MavenEnvironment.cs @@ -287,6 +287,8 @@ public RepositorySystemSession CreateRepositorySystemSession(bool noError = fals session.setTransferListener(new MavenTransferListener(log, noError)); session.setRepositoryListener(new MavenRepositoryListener(log)); session.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, "true"); + session.setSystemProperty("java.version", java.lang.System.getProperty("java.version") ?? "1.8"); + session.setOffline(settings.isOffline()); return session; } diff --git a/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItem.cs b/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItem.cs index 1252c02..d8c8c53 100644 --- a/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItem.cs +++ b/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItem.cs @@ -1,5 +1,5 @@ using System; -using System.Collections.Generic; +using System.Linq; using org.eclipse.aether.util.artifact; @@ -47,11 +47,17 @@ class MavenReferenceItem : IEquatable /// public string Scope { get; set; } = JavaScopes.COMPILE; + /// + /// Gets the exclusions of this reference. + /// + public MavenReferenceItemExclusion[] Exclusions { get; set; } + /// /// Originator of the reference item. /// public string ReferenceSource { get; set; } + /// public override bool Equals(object obj) { return Equals(obj as MavenReferenceItem); @@ -72,6 +78,7 @@ public bool Equals(MavenReferenceItem other) Version == other.Version && Optional == other.Optional && Scope == other.Scope && + Enumerable.SequenceEqual(Exclusions, Exclusions) && ReferenceSource == other.ReferenceSource; } @@ -81,16 +88,7 @@ public bool Equals(MavenReferenceItem other) /// public override int GetHashCode() { - int hashCode = 1928079503; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ItemSpec); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(GroupId); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ArtifactId); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Classifier); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Version); - hashCode = hashCode * -1521134295 + Optional.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Scope); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ReferenceSource); - return hashCode; + return HashCode.Combine(HashCode.Combine(ItemSpec, GroupId, ArtifactId, Classifier, Version, Optional, Scope, Exclusions), ReferenceSource); } /// diff --git a/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemExclusion.cs b/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemExclusion.cs new file mode 100644 index 0000000..6e9b2fc --- /dev/null +++ b/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemExclusion.cs @@ -0,0 +1,75 @@ +using System; + +namespace IKVM.Maven.Sdk.Tasks +{ + + public class MavenReferenceItemExclusion : IEquatable + { + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public MavenReferenceItemExclusion(string groupId, string artifactId, string classifier, string extension) + { + GroupId = groupId ?? throw new ArgumentNullException(nameof(groupId)); + ArtifactId = artifactId ?? throw new ArgumentNullException(nameof(artifactId)); + Classifier = classifier; + Extension = extension; + } + + /// + /// The Maven group ID. Required. + /// + public string GroupId { get; set; } + + /// + /// The Maven artifact ID. Required. + /// + public string ArtifactId { get; set; } + + /// + /// Gets the classifier of the exclusion. + /// + public string Classifier { get; set; } + + /// + /// Gets the extension ID of the exclusion. + /// + public string Extension { get; set; } + + /// + public override bool Equals(object obj) + { + return Equals(obj as MavenReferenceItemExclusion); + } + + /// + public override int GetHashCode() + { + return HashCode.Combine(GroupId, ArtifactId, Classifier, Extension); + } + + /// + /// Returns true if the this item is equal to the other item. + /// + /// + /// + public bool Equals(MavenReferenceItemExclusion other) + { + return other is not null && GroupId == other.GroupId && ArtifactId == other.ArtifactId && Classifier == other.Classifier && Extension == other.Extension; + } + + + /// + public override string ToString() + { + return $"{GroupId}:{ArtifactId}"; + } + + } + +} \ No newline at end of file diff --git a/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemMetadata.cs b/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemMetadata.cs index 54d18e7..856828d 100644 --- a/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemMetadata.cs +++ b/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemMetadata.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Microsoft.Build.Framework; @@ -19,6 +20,7 @@ static class MavenReferenceItemMetadata public static readonly string Dependencies = "Dependencies"; public static readonly string Scope = "Scope"; public static readonly string Optional = "Optional"; + public static readonly string Exclusions = "Exclusions"; public static readonly string Debug = "Debug"; public static readonly string ReferenceSource = "ReferenceSource"; @@ -39,6 +41,7 @@ public static void Save(MavenReferenceItem item, ITaskItem task) task.SetMetadata(MavenReferenceItemMetadata.Version, item.Version); task.SetMetadata(MavenReferenceItemMetadata.Optional, item.Optional ? "true" : "false"); task.SetMetadata(MavenReferenceItemMetadata.Scope, item.Scope); + task.SetMetadata(MavenReferenceItemMetadata.Exclusions, string.Join(";", item.Exclusions.Select(i => i.ToString()))); task.SetMetadata(MavenReferenceItemMetadata.ReferenceSource, item.ReferenceSource); } @@ -65,6 +68,7 @@ public static MavenReferenceItem[] Import(IEnumerable tasks) item.Version = task.GetMetadata(MavenReferenceItemMetadata.Version); item.Optional = string.Equals(task.GetMetadata(MavenReferenceItemMetadata.Optional), "true", StringComparison.OrdinalIgnoreCase); item.Scope = task.GetMetadata(MavenReferenceItemMetadata.Scope); + item.Exclusions = task.GetMetadata(MavenReferenceItemMetadata.Exclusions).Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(i => ParseExclusion(i)).Where(i => i != null).ToArray(); item.ReferenceSource = task.GetMetadata(MavenReferenceItemMetadata.ReferenceSource); list.Add(item); } @@ -73,6 +77,26 @@ public static MavenReferenceItem[] Import(IEnumerable tasks) return list.ToArray(); } + /// + /// Parses a compressed exclusion string. + /// + /// + /// + /// + static MavenReferenceItemExclusion ParseExclusion(string value) + { + var a = value.Split(':'); + if (a.Length is 2 or 3 or 4) + { + var groupId = a[0]; + var artifactId = a[1]; + var classifier = a.Length >= 3 ? a[2] : null; + var extension = a.Length >= 4 ? a[3] : null; + return new MavenReferenceItemExclusion(groupId, artifactId, classifier, extension); + } + + return null; + } } } diff --git a/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemPrepare.cs b/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemPrepare.cs index 1959fe0..80360af 100644 --- a/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemPrepare.cs +++ b/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemPrepare.cs @@ -75,31 +75,31 @@ ITaskItem ToTaskItem(MavenReferenceItem item) void AssignMetadata(MavenReferenceItem item) { if (string.IsNullOrWhiteSpace(item.ItemSpec) == false) - { - var a = item.ItemSpec.Split(':'); - if (a.Length is 2 or 3) { - // itemspec may set various properties - var groupId = a[0]; - var artifactId = a[1]; - var version = a.Length >= 3 ? a[2] : null; - - // if the itemspec is parsable as coordinates, we should attempt to apply or validate metadata - if (string.IsNullOrWhiteSpace(item.GroupId)) - item.GroupId = groupId; - else if (item.GroupId != groupId) - throw new MavenTaskMessageException("Error.MavenInvalidGroupId", item.ItemSpec); - - if (string.IsNullOrWhiteSpace(item.ArtifactId)) - item.ArtifactId = artifactId; - else if (item.ArtifactId != artifactId) - throw new MavenTaskMessageException("Error.MavenInvalidArtifactId", item.ItemSpec); - - if (string.IsNullOrWhiteSpace(item.Version)) - item.Version = version; - else if (version != null && item.Version != version) - throw new MavenTaskMessageException("Error.MavenInvalidVersion", item.ItemSpec); - } + var a = item.ItemSpec.Split(':'); + if (a.Length is 2 or 3) + { + // itemspec may set various properties + var groupId = a[0]; + var artifactId = a[1]; + var version = a.Length >= 3 ? a[2] : null; + + // if the itemspec is parsable as coordinates, we should attempt to apply or validate metadata + if (string.IsNullOrWhiteSpace(item.GroupId)) + item.GroupId = groupId; + else if (item.GroupId != groupId) + throw new MavenTaskMessageException("Error.MavenInvalidGroupId", item.ItemSpec); + + if (string.IsNullOrWhiteSpace(item.ArtifactId)) + item.ArtifactId = artifactId; + else if (item.ArtifactId != artifactId) + throw new MavenTaskMessageException("Error.MavenInvalidArtifactId", item.ItemSpec); + + if (string.IsNullOrWhiteSpace(item.Version)) + item.Version = version; + else if (version != null && item.Version != version) + throw new MavenTaskMessageException("Error.MavenInvalidVersion", item.ItemSpec); + } } if (string.IsNullOrWhiteSpace(item.GroupId)) diff --git a/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemResolve.cs b/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemResolve.cs index 110858c..5924da2 100644 --- a/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemResolve.cs +++ b/src/IKVM.Maven.Sdk.Tasks/MavenReferenceItemResolve.cs @@ -246,7 +246,10 @@ DependencyNode ResolveCompileDependencyGraph(IkvmMavenEnvironment maven, Reposit // convert set of incoming items into a dependency list var dependencies = new Dependency[items.Count]; for (int i = 0; i < items.Count; i++) - dependencies[i] = new Dependency(new DefaultArtifact(items[i].GroupId, items[i].ArtifactId, items[i].Classifier, "jar", items[i].Version), items[i].Scope, items[i].Optional ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE, new java.util.ArrayList()); + { + var exclusions = Arrays.asList(items[i].Exclusions.Select(j => new Exclusion(j.GroupId, j.ArtifactId, j.Classifier, j.Extension)).ToArray()); + dependencies[i] = new Dependency(new DefaultArtifact(items[i].GroupId, items[i].ArtifactId, items[i].Classifier, "jar", items[i].Version), items[i].Scope, items[i].Optional ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE, exclusions); + } // check the cache var root = ResolveCompileDependencyGraphFromCache(maven, dependencies);