-
Notifications
You must be signed in to change notification settings - Fork 536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Xamarin.Android.Build.Tasks] Enable POM verification features. #8649
Conversation
29098c7
to
49bf4a5
Compare
651997c
to
1659801
Compare
e4881ef
to
cfceb52
Compare
<UsingTask TaskName="Xamarin.Android.Tasks.JavaDependencyVerification" AssemblyFile="Xamarin.Android.Build.Tasks.dll" /> | ||
|
||
<Target Name="_VerifyJavaDependencies" | ||
Condition=" '@(AndroidLibrary->Count())' != '0' " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though we "strongly suggest" people use the new item name, there are some using the old one.
Can this check $(_AndroidGenerateManagedBindings)
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As written, none of these new features will function on the "legacy" item names.
For example:
<!-- Satisfies the Java dependency verifier -->
<AndroidLibrary Include="mylib.jar" Pack="false" JavaArtifact="com.example.mylib" JavaVersion="1.0.0" />
<!-- Does not satisfy the Java dependency verifier -->
<InputJar Include="mylib.jar" JavaArtifact="com.example.mylib" JavaVersion="1.0.0" />
Running it on a project that does not have <AndroidLibrary>
will waste time.
Maybe we should take a stronger stance and add a deprecation warning for the legacy items in .NET 9 and remove them in .NET 10?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can begin taking a stance and start warning on usage of legacy item names. That doesn't require that we remove support for them entirely, but it's required before we remove support for them entirely…
try { | ||
var http = new HttpClient (); | ||
var json = await http.GetStringAsync ("https://aka.ms/ms-nuget-packages"); | ||
var outfile = Path.Combine (MavenCacheDirectory, $"microsoft-packages-{DateTime.Today:yyyyMMdd}.json"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we actually put this file in obj
, so if users do a Clean
it will download again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like this file is similar to a NuGet artifact and should be shared and cached across projects. If you are working without internet, it would also be nice if you got to keep using one you previously downloaded.
This logic will attempt to download a new one each day, but will keep the previous one if it can't get a new one.
I don't think this file will change extremely frequently as it does not include version numbers. It will only change when we bind a new AndroidX/GPS library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned about this "per-day" file:
The filesystem is a machine-global, barely concurrent-friendly, "database" with which it's easy to cause "spooky action at a distance".
MavenCacheDirectory
is $(MavenCacheDirectory)
, which is e.g. $(LocalAppData)\dotnet-android\MavenCacheDirectory\
.
What happens if, through some terrible confluence of events, two projects are built at the same time, on the same machine, for the first time "today"? Depending on timing, they may each see that today's microsoft-packages-*.json
doesn't exist, each attempt to create it, and one of them will "lose", possibly causing some variation on our favorite "file share exception" or whatever.
This feels like a potential source of build un-reliability.
This also feels like an impediment to future changes: we can't change the file format. If we have both .NET 9 and .NET 10 installed on a given machine, and these files are stored "machine global", then there is an implicit requirement that .NET 9 be able to consume .NET 10 output, i.e. the file format either can't change, or the file format needs to be "extensible".
I'd feel much "safer" if this file were stored in $(IntermediateOutputPath)
. Lower risk of file share -related errors due to concurrent project builds, no chance of file format-related mismatches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if, through some terrible confluence of events, two projects are built at the same time, on the same machine, for the first time "today"? Depending on timing, they may each see that today's microsoft-packages-*.json doesn't exist, each attempt to create it, and one of them will "lose", possibly causing some variation on our favorite "file share exception" or whatever.
If this scenario were to happen, the "losing" project would log a build message saying it couldn't download the file, and any dependency verification errors would not provide NuGet recommendations. On subsequent builds the NuGet recommendations would be available.
This file is considered "optional" and simply enhances the error messages. However failure is a possible outcome (like if the user doesn't have internet) that is handled and still provides the core experience.
i.e. the file format either can't change, or the file format needs to be "extensible"
The file format is JSON, making it easily extensible if desired in the future. If it needed to be extended somehow that JSON couldn't handle we would likely just rename the new version to something like microsoft-packages-v2.json
.
I'd feel much "safer" if this file were stored in $(IntermediateOutputPath). Lower risk of file share -related errors due to concurrent project builds, no chance of file format-related mismatches.
I really like that we're only downloading this file once per day no matter how many projects one is using, and that any project can use the machine-wide one if internet isn't available. But we can change it if we still have strong concerns.
src/Xamarin.Android.Build.Tasks/Tasks/GetMicrosoftNuGetPackagesMap.cs
Outdated
Show resolved
Hide resolved
src/Xamarin.Android.Build.Tasks/Tasks/JavaDependencyVerification.cs
Outdated
Show resolved
Hide resolved
src/Xamarin.Android.Build.Tasks/Tasks/JavaDependencyVerification.cs
Outdated
Show resolved
Hide resolved
I think that "somewhere" we need a "rewrite"/"update" of the Binding a Java Library docs, and a new (Also, What currently exists in this PR "jumps in" without providing broader context. For example:
I believe that the way to "know" this is happening is via
Does this mean that NuGet packages will contain
A more actionable error message would be useful. Could a "suggested" |
b73b3f3
to
0026d5f
Compare
Agreed, it's on my list for the .NET 9 timeframe. However we still don't have a place for our
Removed "and include" as that could be interpreted that the
This is not the best example, as we do maintain a binding for
In cases where Microsoft does not maintain a binding for the library I'm not sure we can provide an accurate suggestion, as there are many ways to fulfill the dependency and we do not know the best way for the user's scenario. We could add an |
Context: dotnet/android#8649 Add a new `Java.Interop.Tools.Maven.dll` assembly that contains functionality for: - Retrieving artifacts from Maven - Parsing and understanding POM files This assembly is used by dotnet/android#8649 and replaces our previous usage of [`MavenNet.dll`][0]. `Java.Interop.Tools.Maven.dll` contains a binding of [`maven-4.0.0.xsd`][1], generated via [dotnet-xscgen][2]. To update the binding: # Install the binding utility % dotnet tool install -g dotnet-xscgen # Grab the version of `maven*.xsd` you want to bind/update to % curl -o maven-4.0.0.xsd https://maven.apache.org/xsd/maven-4.0.0.xsd # `dotnet tool install` installs into e.g. `$HOME/.dotnet/tools`, which might not be in `$PATH`… # Run the `UpdateProjectSchema` target % PATH=$HOME/.dotnet/tools:$PATH dotnet build -t:UpdateProjectSchema \ src/Java.Interop.Tools.Maven/Java.Interop.Tools.Maven.csproj \ -p:MavenXsd=`pwd`/maven-4.0.0.xsd [0]: https://www.nuget.org/packages/MavenNet [1]: https://maven.apache.org/xsd/maven-4.0.0.xsd [2]: https://www.nuget.org/packages/dotnet-xscgen
9797f91
to
516fd07
Compare
|
||
The specified Maven repository is invalid. | ||
|
||
For example the following Maven repository must be specified with `https://`: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This requirement should be part of the %(AndroidMavenLibrary.Repository)
documentation. :-)
Additionally, what other constraints/requirements/etc. are there? Can a "full URL prefix" be used a'la https://example.com/my/maven/library/path
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not exactly sure what a "full URL prefix" is. The URL should point to a Maven repository, like https://dl.google.com/android/maven2/
or https://repo1.maven.org/maven2/
.
1313ab5
to
b5729ff
Compare
2b7e197
to
d1d938b
Compare
d1d938b
to
6996ccc
Compare
Fix formatting.
if (suggestion is string nuget) | ||
log.LogCodedError ("XA4242", Properties.Resources.XA4242, artifact_spec, nuget); | ||
else | ||
log.LogCodedError ("XA4242", Properties.Resources.XA4241, artifact_spec); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be "XA4241"
, not "XA4242"
, based on the Properties.Resources.XA4241
property name.
if (!all_files.Any (x => x.IsToday)) { | ||
// No file for today, download a new one | ||
try { | ||
using var http = new HttpClient (); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HttpClient
instances should be in static
fields; see also:
* main: [ci] Use managed identity for ApiScan (#8823) [Xamarin.Android.Build.Tasks] DTBs should not rm generator output (#8706) [Xamarin.Android.Build.Tasks] Bump to NuGet 6.7.1 (#8833) $(AndroidPackVersionSuffix)=preview.4; net9 is 34.99.0.preview.4 (#8831) Localized file check-in by OneLocBuild Task (#8824) [Xamarin.Android.Build.Tasks] Enable POM verification features. (#8649) [runtime] Optionally disable inlining (#8798) Fix assembly count when satellite assemblies are present (#8790) [One .NET] new "greenfield" projects are trimmed by default (#8805) Localized file check-in by OneLocBuild Task (#8819) LEGO: Merge pull request 8820
* main: [ci] Use managed identity for ApiScan (#8823) [Xamarin.Android.Build.Tasks] DTBs should not rm generator output (#8706) [Xamarin.Android.Build.Tasks] Bump to NuGet 6.7.1 (#8833) $(AndroidPackVersionSuffix)=preview.4; net9 is 34.99.0.preview.4 (#8831) Localized file check-in by OneLocBuild Task (#8824) [Xamarin.Android.Build.Tasks] Enable POM verification features. (#8649) [runtime] Optionally disable inlining (#8798) Fix assembly count when satellite assemblies are present (#8790) [One .NET] new "greenfield" projects are trimmed by default (#8805) Localized file check-in by OneLocBuild Task (#8819) LEGO: Merge pull request 8820 LEGO: Merge pull request 8818 Bump to dotnet/installer@b40c44502d 9.0.100-preview.3.24165.20 (#8817) Bump com.android.tools:r8 from 8.2.47 to 8.3.37 (#8816) [Mono.Android] Prevent NullPointerException in TranslateStackTrace (#8795) Localized file check-in by OneLocBuild Task (#8815) [Xamarin.Android.Build.Tasks] Make all assemblies RID-specific (#8478) Localized file check-in by OneLocBuild Task (#8813)
* main: Bump to dotnet/installer@dc43d363d2 9.0.100-preview.4.24175.5 (#8828) [Xamarin.Android.Build.Tasks] Update to newer ILRepack which supports debug files. (#8839) Bump 'NuGet.*' and 'Newtonsoft.Json' NuGet versions. (#8825) Localized file check-in by OneLocBuild Task (#8844) [LayoutBindings] Fix '[Preserve]' is obsolete warnings (#8529) LEGO: Merge pull request 8837 [ci] Use managed identity for ApiScan (#8823) [Xamarin.Android.Build.Tasks] DTBs should not rm generator output (#8706) [Xamarin.Android.Build.Tasks] Bump to NuGet 6.7.1 (#8833) $(AndroidPackVersionSuffix)=preview.4; net9 is 34.99.0.preview.4 (#8831) Localized file check-in by OneLocBuild Task (#8824) [Xamarin.Android.Build.Tasks] Enable POM verification features. (#8649) [runtime] Optionally disable inlining (#8798) Fix assembly count when satellite assemblies are present (#8790) [One .NET] new "greenfield" projects are trimmed by default (#8805) Localized file check-in by OneLocBuild Task (#8819) LEGO: Merge pull request 8820
Fixes: #4528
Context: #8420
Building on our previous work enabling
<AndroidMavenLibrary>
, this adds the second piece we would like to support: using POM files to ensure all required Java dependencies are fulfilled. This is a critical step that users often miss or make mistakes, resulting in non-functional bindings.The commit contains complete documentation, so only a summary is provided here.
Adding the following
<AndroidMavenLibrary>
to a binding project:Will produce the following errors:
This is accomplished by automatically downloading the POM file (and any needed parent/imported POM files) for the specified artifact and using them to determine all required dependencies.
There are many documented ways of fixing these errors, the best way is adding the latest versions of the suggested NuGet packages:
Note this commit replaces our previous usage of
MavenNet
withJava.Interop.Tools.Maven
. Thus it removes theMavenNet
TPN.Some future concerns:
<ProjectReference>
? Today, the user must manually add the attributesJavaArtifact
andJavaVersion
to the<ProjectReference>
to specify this.aka.ms
link to point to the permanent home later.