Skip to content
This repository has been archived by the owner on Apr 28, 2022. It is now read-only.

net461 support and thrift.dll #178

Closed
Lercher opened this issue Jun 12, 2020 · 21 comments
Closed

net461 support and thrift.dll #178

Lercher opened this issue Jun 12, 2020 · 21 comments

Comments

@Lercher
Copy link

Lercher commented Jun 12, 2020

Requirement - what kind of business use case are you trying to solve?

Instrumenting an existing .Net Framework 4.6.1 application and using UDP for communication with a local jaeger agent.

Problem - what in Jaeger blocks you from solving the requirement?

The Thrift reference. Adding New Jaeger.Senders.Thrift.UdpSender() to the remote reporter builder raises the exception

System.IO.FileNotFoundException: 
'Could not load file or assembly 'Thrift, Version=0.13.0.0, Culture=neutral, PublicKeyToken=5792536a45833b9f' 
or one of its dependencies. 
The system cannot find the file specified.'

I've fiddled with this situation and I guess the root cause is that the nuget package of Apache thrift publishes a thrift.dll for netstandard and a thrift45.dll for net45, which is used for the net461 project. Moreover these two dlls expose quite a different public API. Manually referencing thrift's netstandard2 library seems to work formally, but I have a bad feeling about this.

Proposal - what do you suggest to solve the problem or improve the existing situation?

I really don't know. Experimentally copying the client's sources to new net461 cs-projects, using thrift's nuget and building it fails b/c of thrift's different API for net45/netstandard.

Any open questions to address

Importing thrift induces a lot of dependencies. If there is need to export a COM API all must be GAC-able and thus strong named. Moving all these dependencies to the jaeger agent (written in go, so there is no actual "moving") and having a very slim variant of the client that can only communicate with the agent via a single fixed protocol could be an option.

@Falco20019
Copy link
Collaborator

I what perspective is the public API different?

@Lercher
Copy link
Author

Lercher commented Jun 12, 2020

This Thrift:
image

Adds this reference:
image
with path D:\Daten\github.com\jaegertracing\jaeger-client-csharp\packages\ApacheThrift.0.13.0.1\lib\net45\Thrift45.dll

Running my sample console app then bombs with
image


Object explorer then shows this. Note the [Thrift] and [Thrift45] markers that are displayed where differences are recognized by my VS2017:
image

This happens on a modern 64bit Win10 client, where I wanted to reproduce my problem. What puzzles me right now is that I have a different machine (32bit Win7 that I must support, sorry) where the two thrift.dll differences are more dramatic, e.g. there is no TProtocol at all, which hinders the thrift sender to compile. Nevermind though, I must investigate that issue in the first place.


N.B.: additional references coming with thrift:
AddingThrift13.txt

@Falco20019
Copy link
Collaborator

You should not add a dependency on ApacheThrift yourself. Use the transitive dependency through Jaeger. Only that way you will end up with the correct netstandard version of Apache. See dotnet/sdk#1791 (comment)

@Lercher
Copy link
Author

Lercher commented Jun 12, 2020

On API differences compiling Jaeger.Thrift: Its a lot of using errors like

1>D:\Daten\lsservice\Jaeger.Thrift\Agent\AggregationValidator.cs(15,23,15,31): error CS0234: The type or namespace name 'Entities' does not exist in the namespace 'Thrift.Protocol' (are you missing an assembly reference?)
1>D:\Daten\lsservice\Jaeger.Thrift\Agent\AggregationValidator.cs(16,23,16,32): error CS0234: The type or namespace name 'Utilities' does not exist in the namespace 'Thrift.Protocol' (are you missing an assembly reference?)
1>D:\Daten\lsservice\Jaeger.Thrift\Agent\AggregationValidator.cs(18,14,18,23): error CS0234: The type or namespace name 'Processor' does not exist in the namespace 'Thrift' (are you missing an assembly reference?)

and then a lot of doesn't implement like that:

1>D:\Daten\lsservice\Jaeger.Thrift\Span.cs(22,31,22,36): error CS0535: 'Span' does not implement interface member 'TBase.Read(TProtocol)'
1>D:\Daten\lsservice\Jaeger.Thrift\Span.cs(22,31,22,36): error CS0535: 'Span' does not implement interface member 'TAbstractBase.Write(TProtocol)'
1>D:\Daten\lsservice\Jaeger.Thrift\ClientStats.cs(19,38,19,43): error CS0535: 'ClientStats' does not implement interface member 'TBase.Read(TProtocol)'
1>D:\Daten\lsservice\Jaeger.Thrift\ClientStats.cs(19,38,19,43): error CS0535: 'ClientStats' does not implement interface member 'TAbstractBase.Write(TProtocol)'
1>D:\Daten\lsservice\Jaeger.Thrift\Collector.cs(34,27,34,38): error CS0246: The type or namespace name 'TBaseClient' could not be found (are you missing a using directive or an assembly reference?)
1>D:\Daten\lsservice\Jaeger.Thrift\Collector.cs(34,40,34,51): error CS0535: 'Collector.Client' does not implement interface member 'IDisposable.Dispose()'
1>D:\Daten\lsservice\Jaeger.Thrift\Collector.cs(73,35,73,51): error CS0246: The type or namespace name 'ITAsyncProcessor' could not be found (are you missing a using directive or an assembly reference?)
1>D:\Daten\lsservice\Jaeger.Thrift\Agent\Agent.cs(36,40,36,51): error CS0535: 'Agent.Client' does not implement interface member 'IDisposable.Dispose()'
1>D:\Daten\lsservice\Jaeger.Thrift\Log.cs(22,30,22,35): error CS0535: 'Log' does not implement interface member 'TBase.Read(TProtocol)'
1>D:\Daten\lsservice\Jaeger.Thrift\Log.cs(22,30,22,35): error CS0535: 'Log' does not implement interface member 'TAbstractBase.Write(TProtocol)'

which is probably caused by thrift's different async implementation model.

@Falco20019
Copy link
Collaborator

Falco20019 commented Jun 12, 2020

Yes I checked the code base for thrift. net45 is only for comparability with code generated as „csharp“. We generate as „netstd“. Make sure to not reference ApacheThrift in your own csproj to avoid this problem.

See the link one post above for an explanation. It’s a problem with how NuGet selects packages. And there is no other workaround than having a separate csproj targeting netstandard and inheriting the dependencies. As jaeger only targets netstandard, you just have to remove your manual NuGet reference.

@Lercher
Copy link
Author

Lercher commented Jun 12, 2020

Yeah. Made a new net461 project, added the nuget Successfully installed 'Jaeger 0.3.7' to JaegerFw461Sample and it reports

This is a FW 4.6.1 sample

Tracer(ServiceName=someService, Version=CSharp-0.3.7.0, Reporter=RemoteReporter(Sender=UdpSender(UdpTransport=ThriftUdpClientTransport(Client=127.0.0.1:6831))), Sampler=ConstSampler(True), IPv4=-1062731278, Tags=[jaeger.version, CSharp-0.3.7.0], [hostname, ITEM-S69570], [ip, 192.168.1.242], ZipkinSharedRpcSpan=False, ExpandExceptionLogs=False, UseTraceId128Bit=False)

I'm just probably too dumb for this. So sorry. Thanks for your help!

@Lercher Lercher closed this as completed Jun 12, 2020
@Falco20019
Copy link
Collaborator

Falco20019 commented Mar 14, 2021

@razbezhkin Glad that you found it out yourself. Just make sure to dispose your tracer (or call CloseAsync) when closing your application. This will ensure it at least tries to send the spans before exiting. Dispose calls CloseAsync with a CancellationToken that times out after 15 seconds. The RemoteReporter itself has a timeout of 10 seconds when disposed. So if sending the span is not possible immediately, it will still try for 10-15 seconds to finalize it.

@yury-kozlov
Copy link

yury-kozlov commented May 24, 2021

@Lercher Can you please advise how the problem solved on your end ? I'm facing the same issue: when creating a console application for .net framework 4.6.1 and adding nuget Jaeger 1.0.0 with a code below I got exception Could not load file or assembly 'Thrift, Version=0.13.0.0, Culture=neutral, PublicKeyToken=5792536a45833b9f'

  var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory();
  Jaeger.Configuration.SenderConfiguration.DefaultSenderResolver = new Jaeger.Senders.SenderResolver(loggerFactory)
      .RegisterSenderFactory<Jaeger.Senders.Thrift.ThriftSenderFactory>();
  
  // this line throws exception:
  var sender = new Jaeger.Configuration.SenderConfiguration(loggerFactory).GetSender();

Only after I copied manually packages\ApacheThrift.0.13.0.1\lib\netstandard2.0\Thrift.dll into the bin folder the issue won't happen. But as mentioned in one of the posts above this is not supposed to be a solution.

@Falco20019
Copy link
Collaborator

Falco20019 commented May 24, 2021

@yury-kozlov Make sure to not reference ApacheThrift in your csproj to use the the one coming from referencing Jaeger. Otherwise, you might be running into the issue discussed here: dotnet/sdk#1791 (comment)

If you try to run it on another machine, make sure to use the publish option instead of copying just the bin folder. This will ensure that all DLLs are where they belong.

Let me know if that removes your problem, otherwise I will give it another look.

@yury-kozlov
Copy link

yury-kozlov commented May 24, 2021

@Falco20019 what do you mean:

Make sure to not reference ApacheThrift directly but to use the the one coming from referencing Jaeger.

As a nuget reference I only added official Jaeger package without anything else (based on clean console application project with .net 4.61).
As a class reference I only used Jaeger.Senders.Thrift.ThriftSenderFactory which comes from jaeger package (see code example above).
Adding packages\ApacheThrift.0.13.0.1\lib\netstandard2.0\Thrift.dll to bin folder is just an experiment - without doing this I get an exception "Could not load file or assembly"

@Falco20019
Copy link
Collaborator

Falco20019 commented May 24, 2021

Can you check if you have a Thrift45.dll in your folder? This issue above happens when you have a .NET project, referencing ApacheThrift directly. This will lead to the project using the .NET Framework 4 version instead of the .NET Standard Version and therefore will not work.

This should not happen if you do not reference ApacheThrift directly and only reference Jaeger. Can you post your csproj? Is this a minimal dummy project that you created or an existing one?

.NET Framework 4.6.1 only has limited support for .NET Standard which is where this problem comes from. So if you are not bound to that version, I would always recommend a version of 4.7.2 or higher. A good explanation of why can be found here: https://weblog.west-wind.com/posts/2019/Feb/19/Using-NET-Standard-with-Full-Framework-NET

Other than that, debugging directly should work and using publish should work. Only running it from bin directly will not work with 4.6.1 since the proxy DLLs are missing. Also your app.config should contain some entries automatically created (ending up in the YourApplication.exe.config in bin).

@yury-kozlov
Copy link

yury-kozlov commented May 24, 2021

Yes I do have Thrift45.dll in the bin\debug folder.
Yes this is a minimal .net framework 4.6.1 project created from a default Visual Studio 2017 template (console application).
The same issue also happens with a minimal .net framework 4.7.2 project.
The issue also happens during debugging.
App.config doesn't contain any binding redirects related to jaeger or thrift (only System.Buffers and System.Runtime.CompilerServices.Unsafe bindings which shouldn't be related to the issue).

This is csproj from framework 4.6.1:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{353CE51F-CC6D-4843-87C6-D930F30FA05C}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <RootNamespace>JaegerClientCSTest</RootNamespace>
    <AssemblyName>JaegerClientCSTest</AssemblyName>
    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="Jaeger.Communication.Thrift, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9516061555a213a8, processorArchitecture=MSIL">
      <HintPath>..\packages\Jaeger.Communication.Thrift.1.0.0\lib\netstandard2.0\Jaeger.Communication.Thrift.dll</HintPath>
    </Reference>
    <Reference Include="Jaeger.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9516061555a213a8, processorArchitecture=MSIL">
      <HintPath>..\packages\Jaeger.Core.1.0.0\lib\netstandard2.0\Jaeger.Core.dll</HintPath>
    </Reference>
    <Reference Include="Jaeger.Senders.Thrift, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9516061555a213a8, processorArchitecture=MSIL">
      <HintPath>..\packages\Jaeger.Senders.Thrift.1.0.0\lib\netstandard2.0\Jaeger.Senders.Thrift.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.AspNetCore.Http.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.AspNetCore.Http.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Abstractions.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.AspNetCore.Http.Features, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.AspNetCore.Http.Features.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Features.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Configuration, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Configuration.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Configuration.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Configuration.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Configuration.Binder, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Configuration.Binder.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Configuration.EnvironmentVariables.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.EnvironmentVariables.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Logging, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Logging.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Logging.Configuration, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Logging.Configuration.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Configuration.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Logging.Console, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Logging.Console.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Console.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Logging.Debug, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Logging.Debug.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Debug.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Options, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Options.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Options.ConfigurationExtensions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Extensions.Primitives, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.Extensions.Primitives.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
    </Reference>
    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
      <HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
    </Reference>
    <Reference Include="OpenTracing, Version=0.12.1.0, Culture=neutral, PublicKeyToken=61503406977abdaf, processorArchitecture=MSIL">
      <HintPath>..\packages\OpenTracing.0.12.1\lib\net45\OpenTracing.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
    </Reference>
    <Reference Include="System.ComponentModel.Annotations, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll</HintPath>
    </Reference>
    <Reference Include="System.ComponentModel.DataAnnotations" />
    <Reference Include="System.Core" />
    <Reference Include="System.IO.Pipes, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.IO.Pipes.4.3.0\lib\net46\System.IO.Pipes.dll</HintPath>
      <Private>True</Private>
      <Private>True</Private>
    </Reference>
    <Reference Include="System.IO.Pipes.AccessControl, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.IO.Pipes.AccessControl.4.5.1\lib\net461\System.IO.Pipes.AccessControl.dll</HintPath>
    </Reference>
    <Reference Include="System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll</HintPath>
    </Reference>
    <Reference Include="System.Net.Http.WinHttpHandler, Version=4.0.3.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Net.Http.WinHttpHandler.4.5.2\lib\net461\System.Net.Http.WinHttpHandler.dll</HintPath>
    </Reference>
    <Reference Include="System.Net.NameResolution, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Net.NameResolution.4.3.0\lib\net46\System.Net.NameResolution.dll</HintPath>
      <Private>True</Private>
      <Private>True</Private>
    </Reference>
    <Reference Include="System.Net.Security, Version=4.0.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Net.Security.4.3.2\lib\net46\System.Net.Security.dll</HintPath>
      <Private>True</Private>
      <Private>True</Private>
    </Reference>
    <Reference Include="System.Numerics" />
    <Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
    </Reference>
    <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
    </Reference>
    <Reference Include="System.Runtime.Remoting" />
    <Reference Include="System.Security.AccessControl, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll</HintPath>
    </Reference>
    <Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath>
      <Private>True</Private>
      <Private>True</Private>
    </Reference>
    <Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
      <Private>True</Private>
      <Private>True</Private>
    </Reference>
    <Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
      <Private>True</Private>
      <Private>True</Private>
    </Reference>
    <Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
      <Private>True</Private>
      <Private>True</Private>
    </Reference>
    <Reference Include="System.Security.Principal.Windows, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
    </Reference>
    <Reference Include="System.Text.Encodings.Web, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Text.Encodings.Web.4.5.0\lib\netstandard2.0\System.Text.Encodings.Web.dll</HintPath>
    </Reference>
    <Reference Include="System.Threading.Tasks.Dataflow, Version=4.6.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Threading.Tasks.Dataflow.4.11.1\lib\net461\System.Threading.Tasks.Dataflow.dll</HintPath>
    </Reference>
    <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
    </Reference>
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
    <Reference Include="Thrift45, Version=0.13.0.0, Culture=neutral, PublicKeyToken=5792536a45833b9f, processorArchitecture=MSIL">
      <HintPath>..\packages\ApacheThrift.0.13.0.1\lib\net45\Thrift45.dll</HintPath>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config" />
    <None Include="packages.config" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

@Falco20019
Copy link
Collaborator

Falco20019 commented May 25, 2021

I think you need to use PackageReference instead of packages.config for .NET Standard packages to correctly work. There should be an option to convert the project or it should have asked you what to use.

You can also use the new SDK-style csproj format with TargetFramework set to to net461.

See https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference on how to migrate.

@yury-kozlov
Copy link

yury-kozlov commented May 25, 2021

Unfortunately PackageReference instead of packages.config didn't help:

  • I created a new project from template: .net framework 4.61
    Manually added to csproj:
  <PropertyGroup>
    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
  </PropertyGroup>
  • Installed Jaeger package and made sure it was added to csproj and that file packages.config was not created
  • Built project and still see the Thrift45.dll in the output folder instead of Thrift.dll
    When running a sample application got the same error Could not load file or assembly 'Thrift...
See contents of the new csproj:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
  </PropertyGroup>
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{ECE63D05-F0B4-4C69-B092-29DCEB65437B}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <RootNamespace>JaegerClientCSTest461r</RootNamespace>
    <AssemblyName>JaegerClientCSTest461r</AssemblyName>
    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Jaeger">
      <Version>1.0.0</Version>
    </PackageReference>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

@Lercher
Copy link
Author

Lercher commented May 25, 2021

Hi all, everything was already answered by #178 (comment) As far as I remember, I just removed all references and added only the Jaeger one via nuget. Here is an excerpt from one of my vb.net project files. Hope that helps.

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
  <PropertyGroup>
...
    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
...
<ItemGroup>
    <Reference Include="Jaeger, Version=0.3.7.0, Culture=neutral, PublicKeyToken=9516061555a213a8, processorArchitecture=MSIL">
      <HintPath>..\packages\Jaeger.0.3.7\lib\netstandard2.0\Jaeger.dll</HintPath>
    </Reference>
    <Reference Include="Jaeger.Thrift, Version=0.3.7.0, Culture=neutral, PublicKeyToken=9516061555a213a8, processorArchitecture=MSIL">
      <HintPath>..\packages\Jaeger.Thrift.0.3.7\lib\netstandard2.0\Jaeger.Thrift.dll</HintPath>
    </Reference>
    <Reference Include="Jaeger.Thrift.VendoredThrift, Version=1.0.0.1, Culture=neutral, PublicKeyToken=9516061555a213a8, processorArchitecture=MSIL">
      <HintPath>..\packages\Jaeger.Thrift.VendoredThrift.0.3.7\lib\netstandard2.0\Jaeger.Thrift.VendoredThrift.dll</HintPath>
    </Reference>
   ...
    <Reference Include="OpenTracing, Version=0.12.1.0, Culture=neutral, PublicKeyToken=61503406977abdaf, processorArchitecture=MSIL">
      <HintPath>..\packages\OpenTracing.0.12.1\lib\net45\OpenTracing.dll</HintPath>
    </Reference>
    ...

My app.config contains nothing special.

@yury-kozlov
Copy link

Thank you @Lercher. As I understand, your nuget is Jaeger, Version=0.3.7.0, where everything works fine.
The issue probably started happening in newer versions of Jaeger, for example I experience it in the latest "Jaeger" version="1.0.0".

@Falco20019 This may be related: Could not load file or assembly Thrift, Version=0.13.0.0. In their fix I see that they explicitly provide a hint for Thrift.dll:

<Reference Include="ApacheThrift">
  <HintPath>$(PkgApacheThrift)\lib\netstandard2.0\Thrift.dll</HintPath>
</Reference>

@Falco20019
Copy link
Collaborator

Falco20019 commented May 25, 2021

That‘s a manual workaround that usually should not be necessary. I will need to look into it but won‘t be able to do so until around Thursday :(

The problem here is the one that I linked earlier. The build chain is resolving the transitive dependency using .NET Framework 4.5 instead of .NET Standard 2.0 (which is wrong). But I don‘t really understand why it‘s doing that…

The fix is also adding the following line for setting PkgApacheThrift:
<PackageReference Include="ApacheThrift" Version="0.13.0.1" ExcludeAssets="all" GeneratePathProperty="true" />

@yury-kozlov
Copy link

yury-kozlov commented May 25, 2021

Thanks!
On the example of OpenTelemetry.Exporter.Jaeger I see that in their later commits they removed the dependency ApacheThrift and copied apache sources directly into the package.
So now I'm not sure if their original fix of Thrift.dll was right :(

From the readme:

This was done because the official NuGet has two issues:

  • . . .
  • The nupkg contains a net45 library with a different API than the .NET Standard 2.0 library. This breaks .NET Framework consumers of OpenTelemetry using Jaeger unless we force selection of the lib/netstandard2.0 reference instead.

Ideally we would consume the official package but these issues made it difficult.

@Falco20019
Copy link
Collaborator

Since this issue was closed, let‘s continue the discussion on #212

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
@Falco20019 @Lercher @yury-kozlov and others