This is an automated email from the ASF dual-hosted git repository.
ptupitsyn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 0d5a325 IGNITE-12427 .NET: Fix Mono issues
0d5a325 is described below
commit 0d5a325e4d2f8f7cb72025914055baedec2f0ce1
Author: Pavel Tupitsyn <[email protected]>
AuthorDate: Sun Dec 22 23:00:56 2019 +0300
IGNITE-12427 .NET: Fix Mono issues
* Fix P/Invoke in UnmanagedThread
* Fix GetDefaultAppDomain
* Fix build.ps1 to work on Linux under PowerShell Core
This enables full development cycle on Linux with Mono, including NuGet
package creation
---
.../Binary/BinaryBuilderSelfTest.cs | 4 +-
.../Client/ClientProtocolCompatibilityTest.cs | 4 +-
.../Apache.Ignite.Core.Tests/Examples/Example.cs | 3 +-
.../Apache.Ignite.Core.Tests/Examples/PathUtil.cs | 4 +-
.../dotnet/Apache.Ignite.Core.Tests/TestRunner.cs | 5 +-
.../Apache.Ignite.Core/Impl/Common/TaskRunner.cs | 2 +-
.../Impl/Unmanaged/Jni/AppDomains.cs | 10 ++
.../Impl/Unmanaged/UnmanagedThread.cs | 32 +++++-
modules/platforms/dotnet/build.ps1 | 122 +++++++++++----------
modules/platforms/dotnet/release/verify-nuget.ps1 | 6 +-
10 files changed, 115 insertions(+), 77 deletions(-)
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
index 2880e7e..040d5d1 100644
---
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
+++
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
@@ -617,7 +617,7 @@ namespace Apache.Ignite.Core.Tests.Binary
Assert.AreEqual(-88648479, obj1.GetHashCode());
Assert.AreEqual(obj1.GetHashCode(), obj2.GetHashCode());
- Assert.AreEqual("myType [, int=1, str=foo]",
Regex.Replace(obj1.ToString(), "idHash=\\d+", ""));
+ Assert.AreEqual("myType [, int=1, str=foo]",
Regex.Replace(obj1.ToString(), "idHash=[+-]?\\d+", ""));
}
/// <summary>
@@ -1892,7 +1892,7 @@ namespace Apache.Ignite.Core.Tests.Binary
Assert.AreEqual(obj1, obj2);
Assert.AreEqual(obj1.GetHashCode(), obj2.GetHashCode());
- Assert.AreEqual("sortTest [, a=2, b=1, c=3]",
Regex.Replace(obj1.ToString(), "idHash=\\d+", ""));
+ Assert.AreEqual("sortTest [, a=2, b=1, c=3]",
Regex.Replace(obj1.ToString(), "idHash=[+-]?\\d+", ""));
// Skip header, take 3 fields (type code + value).
var bytes1 = obj1.Data.Skip(24).Take(6).ToArray();
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientProtocolCompatibilityTest.cs
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientProtocolCompatibilityTest.cs
index a6770ff..4e2b747 100644
---
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientProtocolCompatibilityTest.cs
+++
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientProtocolCompatibilityTest.cs
@@ -175,12 +175,12 @@ namespace Apache.Ignite.Core.Tests.Client
/// <summary>
/// Gets the client with specified protocol version.
/// </summary>
- private IgniteClient GetClient(ClientProtocolVersion version, bool
EnableAffinityAwareness = false)
+ private IgniteClient GetClient(ClientProtocolVersion version, bool
enableAffinityAwareness = false)
{
var cfg = new IgniteClientConfiguration(GetClientConfiguration())
{
ProtocolVersion = version,
- EnableAffinityAwareness = EnableAffinityAwareness
+ EnableAffinityAwareness = enableAffinityAwareness
};
return (IgniteClient) Ignition.StartClient(cfg);
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs
index de43666..2859e5f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs
@@ -84,7 +84,8 @@ namespace Apache.Ignite.Core.Tests.Examples
foreach (var type in types)
{
- var sourceFile = sourceFiles.Single(x =>
x.EndsWith(string.Format("\\{0}.cs", type.Name)));
+ var sourceFile = sourceFiles.Single(
+ x => x.EndsWith(string.Format("{0}{1}.cs",
Path.DirectorySeparatorChar, type.Name)));
var sourceCode = File.ReadAllText(sourceFile);
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/PathUtil.cs
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/PathUtil.cs
index b265ea2..969b28b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/PathUtil.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/PathUtil.cs
@@ -34,13 +34,13 @@ namespace Apache.Ignite.Core.Tests.Examples
/// Examples source code path.
/// </summary>
public static readonly string ExamplesSourcePath =
- Path.Combine(IgniteHome, @"modules\platforms\dotnet\examples");
+ Path.Combine(IgniteHome, "modules", "platforms", "dotnet",
"examples");
/// <summary>
/// Examples application configuration path.
/// </summary>
public static readonly string ExamplesAppConfigPath =
- Path.Combine(ExamplesSourcePath,
@"Apache.Ignite.Examples\App.config");
+ Path.Combine(ExamplesSourcePath, "Apache.Ignite.Examples",
"App.config");
/// <summary>
/// Gets the full configuration path.
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
index ab6af60..fef321f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
@@ -24,7 +24,6 @@ namespace Apache.Ignite.Core.Tests
using System.Reflection;
using Apache.Ignite.Core.Tests.Binary.Serializable;
using Apache.Ignite.Core.Tests.Cache;
- using Apache.Ignite.Core.Tests.Cache.Query.Linq;
using Apache.Ignite.Core.Tests.Client.Cache;
using Apache.Ignite.Core.Tests.Compute;
using Apache.Ignite.Core.Tests.Memory;
@@ -74,10 +73,10 @@ namespace Apache.Ignite.Core.Tests
var basicTests = new[]
{
typeof(ComputeApiTest),
- typeof(CacheLinqTest),
typeof(SqlDmlTest),
typeof(LinqTest),
- typeof(PersistenceTest)
+ typeof(PersistenceTest),
+ typeof(CacheTest)
};
Environment.ExitCode = TestAll(basicTests, true);
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/TaskRunner.cs
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/TaskRunner.cs
index 13eec48..b6c8f66 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/TaskRunner.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/TaskRunner.cs
@@ -25,7 +25,7 @@ namespace Apache.Ignite.Core.Impl.Common
/// Extensions for <see cref="Task"/> classes.
/// Fixes the issue with <see cref="TaskScheduler.Current"/> being used by
default by system APIs.
/// Current scheduler can be anything, but in most cases we just want
thread pool when starting a task.
- /// <see cref="TaskScheduler.Default"/> is normally <see
cref="ThreadPoolTaskScheduler"/>.
+ /// <see cref="TaskScheduler.Default"/> is normally
ThreadPoolTaskScheduler.
/// </summary>
internal static class TaskRunner
{
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/Jni/AppDomains.cs
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/Jni/AppDomains.cs
index bb36784..e307ed0 100644
---
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/Jni/AppDomains.cs
+++
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/Jni/AppDomains.cs
@@ -58,6 +58,16 @@ namespace Apache.Ignite.Core.Impl.Unmanaged.Jni
/// </summary>
public static _AppDomain GetDefaultAppDomain()
{
+ if (Os.IsMono)
+ {
+ var prop = typeof(AppDomain).GetProperty(
+ "DefaultDomain", System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Static);
+
+ Debug.Assert(prop != null);
+
+ return (_AppDomain) prop.GetValue(null, null);
+ }
+
object objHost;
int hr = NativeMethods.CLRCreateInstance(ref CLSID_CLRMetaHost,
ref IID_CLRMetaHost, out objHost);
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedThread.cs
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedThread.cs
index b27da51..352d22f 100644
---
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedThread.cs
+++
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedThread.cs
@@ -68,7 +68,9 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
if (Os.IsLinux)
{
int tlsIndex;
- var res = NativeMethodsLinux.pthread_key_create(new
IntPtr(&tlsIndex), callbackPtr);
+ var res = Os.IsMono
+ ? NativeMethodsMono.pthread_key_create(new
IntPtr(&tlsIndex), callbackPtr)
+ : NativeMethodsLinux.pthread_key_create(new
IntPtr(&tlsIndex), callbackPtr);
NativeMethodsLinux.CheckResult(res);
@@ -101,7 +103,10 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
}
else if (Os.IsLinux)
{
- var res = NativeMethodsLinux.pthread_key_delete(callbackId);
+ var res = Os.IsMono
+ ? NativeMethodsMono.pthread_key_delete(callbackId)
+ : NativeMethodsLinux.pthread_key_delete(callbackId);
+
NativeMethodsLinux.CheckResult(res);
}
else
@@ -134,7 +139,10 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
}
else if (Os.IsLinux)
{
- var res = NativeMethodsLinux.pthread_setspecific(callbackId,
threadLocalValue);
+ var res = Os.IsMono
+ ? NativeMethodsMono.pthread_setspecific(callbackId,
threadLocalValue)
+ : NativeMethodsLinux.pthread_setspecific(callbackId,
threadLocalValue);
+
NativeMethodsLinux.CheckResult(res);
}
else
@@ -212,5 +220,23 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
[DllImport("libSystem.dylib")]
public static extern int pthread_setspecific(int key, IntPtr
value);
}
+
+ /// <summary>
+ /// Mono on Linux requires __Internal instead of libcoreclr.so.
+ /// </summary>
+ private static class NativeMethodsMono
+ {
+ [SuppressMessage("Microsoft.Design",
"CA1060:MovePInvokesToNativeMethodsClass", Justification = "Reviewed.")]
+ [DllImport("__Internal")]
+ public static extern int pthread_key_create(IntPtr key, IntPtr
destructorCallback);
+
+ [SuppressMessage("Microsoft.Design",
"CA1060:MovePInvokesToNativeMethodsClass", Justification = "Reviewed.")]
+ [DllImport("__Internal")]
+ public static extern int pthread_key_delete(int key);
+
+ [SuppressMessage("Microsoft.Design",
"CA1060:MovePInvokesToNativeMethodsClass", Justification = "Reviewed.")]
+ [DllImport("__Internal")]
+ public static extern int pthread_setspecific(int key, IntPtr
value);
+ }
}
}
diff --git a/modules/platforms/dotnet/build.ps1
b/modules/platforms/dotnet/build.ps1
index 4db0031..3710d94 100644
--- a/modules/platforms/dotnet/build.ps1
+++ b/modules/platforms/dotnet/build.ps1
@@ -97,6 +97,22 @@ param (
[string]$version=""
)
+# 0) Functions
+function Make-Dir([string]$dirPath) {
+ New-Item -Path $dirPath -ItemType "directory" -Force
+ Remove-Item -Force $dirPath\*.*
+}
+
+function Exec([string]$command) {
+ try {
+ iex "& $command"
+ } catch {
+ echo "Command failed: $command"
+ throw
+ exit -1
+ }
+}
+
# 1) Build Java (Maven)
# Detect Ignite root directory
cd $PSScriptRoot\..
@@ -126,19 +142,14 @@ if (!$skipJava) {
}
# Install Maven Wrapper
- cmd /c "$mv -N io.takari:maven:wrapper -Dmaven=3.5.2"
- $mv = "mvnw.cmd"
+ Exec "$mv --% -N io.takari:maven:wrapper -Dmaven=3.5.2"
+ $mv = If ($IsLinux) { "./mvnw" } else { "mvnw.cmd" }
# Run Maven
echo "Starting Java (Maven) build..."
$mvnTargets = if ($clean) { "clean package" } else { "package" }
- cmd /c "$mv $mvnTargets -DskipTests $mavenOpts"
-
- # Check result
- if ($LastExitCode -ne 0) {
- echo "Java (Maven) build failed."; exit -1
- }
+ Exec "$mv --% $mvnTargets -DskipTests $mavenOpts"
}
else {
echo "Java (Maven) build skipped."
@@ -146,12 +157,12 @@ else {
# Copy (relevant) jars
$libsDir = "$PSScriptRoot\bin\libs"
-mkdir -Force $libsDir; del -Force $libsDir\*.*
+Make-Dir($libsDir)
-ls $jarDirs.Split(',') *.jar -recurse `
+Get-ChildItem $jarDirs.Split(',') *.jar -recurse `
-include
"ignite-core*","ignite-indexing*","ignite-shmem*","ignite-spring*","lucene*","h2*","cache-api*","commons-*","spring*"
`
-exclude "*-sources*","*-javadoc*","*-tests*","*optional*" `
- | % { copy -Force $_ $libsDir }
+ | % { Copy-Item -Force $_ $libsDir }
# Restore directory
cd $PSScriptRoot
@@ -167,43 +178,48 @@ if ((Get-Command $ng -ErrorAction SilentlyContinue) -eq
$null) {
if (-not (Test-Path $ng)) {
echo "Downloading NuGet..."
- (New-Object
System.Net.WebClient).DownloadFile("https://dist.nuget.org/win-x86-commandline/v3.3.0/nuget.exe",
"nuget.exe");
+ (New-Object
System.Net.WebClient).DownloadFile("https://dist.nuget.org/win-x86-commandline/v3.3.0/nuget.exe",
"nuget.exe")
}
}
echo "Using NuGet from: $ng"
if (!$skipDotNet) {
- # Detect MSBuild 4.0+
- for ($i=20; $i -ge 4; $i--) {
- $regKey = "HKLM:\software\Microsoft\MSBuild\ToolsVersions\$i.0"
- if (Test-Path $regKey) { break }
- }
+ $msBuild = "msbuild"
- if (!(Test-Path $regKey)) {
- echo "Failed to detect MSBuild path, exiting."
- exit -1
- }
+ if ((Get-Command $msBuild -ErrorAction SilentlyContinue) -eq $null)
+ {
+ # Detect MSBuild 4.0+
+ for ($i = 20; $i -ge 4; $i--) {
+ $regKey = "HKLM:\software\Microsoft\MSBuild\ToolsVersions\$i.0"
+ if (Test-Path $regKey)
+ {
+ break
+ }
+ }
- $msbuildExe = (join-path -path (Get-ItemProperty
$regKey)."MSBuildToolsPath" -childpath "msbuild.exe")
- echo "MSBuild detected at '$msbuildExe'."
+ if (!(Test-Path $regKey))
+ {
+ echo "Failed to detect MSBuild path, exiting."
+ exit -1
+ }
+
+ $msBuild = (Join-Path -path (Get-ItemProperty
$regKey)."MSBuildToolsPath" -childpath "msbuild.exe")
+ $msBuild = "`"$msBuild`"" # Put in quotes and escape to handle
whitespace in path
+ }
+
+ echo "MSBuild detected at '$msBuild'."
# Restore NuGet packages
echo "Restoring NuGet..."
- & $ng restore Apache.Ignite.sln
+ Exec "$ng restore Apache.Ignite.sln"
# Build
$targets = if ($clean) {"Clean;Rebuild"} else {"Build"}
$codeAnalysis = if ($skipCodeAnalysis) {"/p:RunCodeAnalysis=false"}
else {""}
- $msBuildCommand = "`"$msBuildExe`" Apache.Ignite.sln /target:$targets
/p:Configuration=$configuration /p:Platform=`"$platform`" $codeAnalysis
/p:UseSharedCompilation=false"
+ $msBuildCommand = "$msBuild Apache.Ignite.sln /target:$targets
/p:Configuration=$configuration /p:Platform=`"$platform`" $codeAnalysis
/p:UseSharedCompilation=false"
echo "Starting MsBuild: '$msBuildCommand'"
- cmd /c $msBuildCommand
-
- # Check result
- if ($LastExitCode -ne 0) {
- echo ".NET build failed."
- exit -1
- }
+ Exec $msBuildCommand
}
if(!$skipDotNetCore) {
@@ -213,48 +229,40 @@ if(!$skipDotNetCore) {
if ($clean) {
$cleanCommand = "dotnet clean $targetSolution -c $configuration"
echo "Starting dotnet clean: '$cleanCommand'"
- cmd /c $cleanCommand
+ Exec $cleanCommand
}
$publishCommand = "dotnet publish $targetSolution -c $configuration"
echo "Starting dotnet publish: '$publishCommand'"
- cmd /c $publishCommand
-
- # Check result
- if ($LastExitCode -ne 0) {
- echo ".NET Core build failed."
- exit -1
- }
+ Exec $publishCommand
}
if ($asmDirs) {
- ls $asmDirs.Split(',') | % `
+ Get-ChildItem $asmDirs.Split(',') | % `
{
- $projName = [System.IO.Path]::GetFileNameWithoutExtension($_.Name);
+ $projName = [System.IO.Path]::GetFileNameWithoutExtension($_.Name)
if ($_.Name.EndsWith(".exe.config")) {
- $projName =
[System.IO.Path]::GetFileNameWithoutExtension($projName);
+ $projName =
[System.IO.Path]::GetFileNameWithoutExtension($projName)
}
if ($projName.StartsWith("Apache.Ignite")) {
$target = "$projName\bin\Release"
- mkdir -Force $target
-
- xcopy /s /y $_.FullName $target
+ Make-Dir($target)
}
}
}
# Copy binaries
-mkdir -Force bin; del -Force -Recurse bin\*.*
+Make-Dir("bin")
-ls *.csproj -Recurse | where Name -NotLike "*Examples*" `
+Get-ChildItem *.csproj -Recurse | where Name -NotLike "*Examples*" `
| where Name -NotLike "*Tests*" `
| where Name -NotLike "*Benchmarks*" | % {
- $binDir = if (($configuration -eq "Any CPU") -or ($_.Name -ne
"Apache.Ignite.Core.csproj")) `
+ $binDir = if (($platform -eq "Any CPU") -or ($_.Name -ne
"Apache.Ignite.Core.csproj") -or $IsLinux) `
{"bin\$configuration"} else {"bin\$platform\$configuration"}
- $dir = join-path (split-path -parent $_) $binDir
- xcopy /s /y $dir\*.* bin
+ $dir = join-path (split-path -parent $_) $binDir
+ Copy-Item -Force $dir\*.* bin
}
@@ -267,21 +275,15 @@ if (!$skipNuGet) {
}
$nupkgDir = "nupkg"
- mkdir -Force $nupkgDir; del -Force $nupkgDir\*.*
+ Make-Dir($nupkgDir)
# Detect version
$ver = if ($version) { $version } else { (gi
Apache.Ignite.Core\bin\Release\Apache.Ignite.Core.dll).VersionInfo.ProductVersion
}
# Find all nuspec files and run 'nuget pack' either directly, or on
corresponding csproj files (if present)
- ls *.nuspec -Recurse `
+ Get-ChildItem *.nuspec -Recurse `
| % {
- & $ng pack $_ -Prop Configuration=Release -Prop Platform=AnyCPU
-Version $ver -OutputDirectory $nupkgDir
-
- # check result
- if ($LastExitCode -ne 0)
- {
- echo "NuGet pack failed."; exit -1
- }
+ Exec "$ng pack $_ -Prop Configuration=Release -Prop
Platform=AnyCPU -Version $ver -OutputDirectory $nupkgDir"
}
echo "NuGet packages created in '$pwd\$nupkgDir'."
diff --git a/modules/platforms/dotnet/release/verify-nuget.ps1
b/modules/platforms/dotnet/release/verify-nuget.ps1
index fdde984..c2885bf 100644
--- a/modules/platforms/dotnet/release/verify-nuget.ps1
+++ b/modules/platforms/dotnet/release/verify-nuget.ps1
@@ -48,7 +48,7 @@ if (!(Test-Path $dir)) {
throw "Path does not exist: '$packageDir' (resolved to '$dir')"
}
-$packages = ls $dir *.nupkg
+$packages = Get-ChildItem $dir *.nupkg
if ($packages.Length -eq 0) {
throw "nupkg files not found in '$dir'"
}
@@ -59,8 +59,8 @@ echo "Verifying $($packages.Length) packages from '$dir'..."
# Create test dir
$testDir = Join-Path $PSScriptRoot "test-proj"
-mkdir -Force $testDir
-del -Force $testDir\*.*
+New-Item -Path $testDir -ItemType "directory" -Force
+Remove-Item -Force $testDir\*.*
cd $testDir