Skip to content

Commit 2907321

Browse files
Fix LT-22509: Newtonsoft.Json Method not found error
- Newtonsoft.Json doesn't change assembly versions on minor version bumps. 13.0.4 added a method and we started using it in libpalaso. If a version less than that is installed in the GAC our local version would not be loaded. This patch enforces using our local copy by our application. Change-Id: I9b7cdfbe792fda13b3dcc570c2c5dc8d19e6d596
1 parent 9be9d6b commit 2907321

3 files changed

Lines changed: 57 additions & 0 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Adds <codeBase href="Newtonsoft.Json.dll"> under Newtonsoft.Json dependentAssembly in staged *.config
2+
# so the private 13.0.x DLL wins over an older same-identity (13.0.0.0) GAC build. Param: StagedBinDir.
3+
param([Parameter(Mandatory)][string]$StagedBinDir)
4+
$ErrorActionPreference = 'Stop'
5+
$bin = if ($StagedBinDir) { [IO.Path]::GetFullPath($StagedBinDir) }
6+
if (-not $bin -or -not (Test-Path -LiteralPath $bin -PathType Container)) {
7+
Write-Verbose "Skip: staged bin missing: $StagedBinDir"; return
8+
}
9+
$nj = Join-Path $bin 'Newtonsoft.Json.dll'
10+
if (-not (Test-Path -LiteralPath $nj -PathType Leaf)) {
11+
Write-Verbose "Skip: Newtonsoft.Json.dll missing under $bin"; return
12+
}
13+
$ver = [Reflection.AssemblyName]::GetAssemblyName($nj).Version.ToString()
14+
$ns = 'urn:schemas-microsoft-com:asm.v1'
15+
Get-ChildItem -LiteralPath $bin -Filter '*.config' -File | ForEach-Object {
16+
$path = $_.FullName
17+
$xml = New-Object System.Xml.XmlDocument
18+
try { $xml.Load($path) } catch { Write-Warning "Skip unreadable config $path : $_"; return }
19+
$m = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
20+
[void]$m.AddNamespace('ab', $ns)
21+
$deps = $xml.SelectNodes('//ab:dependentAssembly', $m)
22+
if (-not $deps -or $deps.Count -eq 0) { return }
23+
$changed = $false
24+
foreach ($d in $deps) {
25+
$id = $d.SelectSingleNode('ab:assemblyIdentity', $m)
26+
if (-not $id -or $id.GetAttribute('name') -cne 'Newtonsoft.Json') { continue }
27+
$ok = $false
28+
foreach ($c in @($d.SelectNodes('ab:codeBase', $m))) {
29+
if ($c.GetAttribute('href') -cne 'Newtonsoft.Json.dll') { continue }
30+
if ($c.GetAttribute('version') -ceq $ver) { $ok = $true; break }
31+
[void]$d.RemoveChild($c); $changed = $true
32+
}
33+
if ($ok) { continue }
34+
$cb = $xml.CreateElement('codeBase', $ns)
35+
$cb.SetAttribute('version', $ver); $cb.SetAttribute('href', 'Newtonsoft.Json.dll')
36+
[void]$d.InsertAfter($cb, $id); $changed = $true
37+
}
38+
if ($changed) { $xml.Save($path) }
39+
}

Build/Installer.legacy.targets

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,15 @@
350350
OverwriteReadonlyFiles="true"
351351
DestinationFolder="$(OverridesDestDir)"
352352
/>
353+
<!-- Newtonsoft.Json 13.0.x shares assembly version 13.0.0.0; GAC can win over the private copy. -->
354+
<PropertyGroup>
355+
<NewtonsoftJsonPrivateCodeBaseScript>$(fwrt)\Build\Agent\Patch-NewtonsoftJsonPrivateCodeBase.ps1</NewtonsoftJsonPrivateCodeBaseScript>
356+
</PropertyGroup>
357+
<Exec
358+
Condition="Exists('$(NewtonsoftJsonPrivateCodeBaseScript)')"
359+
Command="powershell -NoProfile -ExecutionPolicy Bypass -File &quot;$(NewtonsoftJsonPrivateCodeBaseScript)&quot; -StagedBinDir &quot;$(AppBuildDir)\$(BinDirSuffix)&quot;"
360+
IgnoreExitCode="false"
361+
/>
353362
<CallTarget Targets="HarvestL10n;ConvertHarvestsToWxi;WriteFilesMetadata" />
354363
</Target>
355364
<Target Name="ValidateInstallerAddons" Condition="'$(BuildAdditionalApps)'=='true'">

Build/Installer.targets

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,15 @@
145145
<Copy SourceFiles="@(IcuDataFiles)" OverwriteReadOnlyFiles="true" DestinationFolder="$(StagedDataDir)\Icu$(IcuVersion)\%(RecursiveDir)" />
146146
<Copy SourceFiles="@(L10nFilesWithRecursiveDirs)" OverwriteReadOnlyFiles="true" DestinationFolder="$(StagedL10nDir)\%(RecursiveDir)" />
147147
<Copy SourceFiles="@(BinFiles)" OverwriteReadOnlyFiles="true" DestinationFolder="$(StagedBinDir)\%(RecursiveDir)" />
148+
<!-- Newtonsoft.Json 13.0.x shares assembly version 13.0.0.0; GAC can win over the private copy. -->
149+
<PropertyGroup>
150+
<NewtonsoftJsonPrivateCodeBaseScript>$(fwrt)\Build\Agent\Patch-NewtonsoftJsonPrivateCodeBase.ps1</NewtonsoftJsonPrivateCodeBaseScript>
151+
</PropertyGroup>
152+
<Exec
153+
Condition="Exists('$(NewtonsoftJsonPrivateCodeBaseScript)')"
154+
Command="powershell -NoProfile -ExecutionPolicy Bypass -File &quot;$(NewtonsoftJsonPrivateCodeBaseScript)&quot; -StagedBinDir &quot;$(StagedBinDir)&quot;"
155+
IgnoreExitCode="false"
156+
/>
148157
</Target>
149158

150159
<Target Name="ValidateInstallerAddons" Condition="'$(BuildAdditionalApps)'=='true'">

0 commit comments

Comments
 (0)