Azure / azure-webjobs-sdk

Azure WebJobs SDK
MIT License
738 stars 358 forks source link

Version 3.x is incompatible with .NET Framework and PackageReference #2186

Open davidmatson opened 5 years ago

davidmatson commented 5 years ago

See comments on #1493; there's no usable workaround when consuming WebJobs SDK 3.x in a project that uses PackageReference rather than the old packages.config.

2076 may be the only feasible solution here.

davidmatson commented 5 years ago

I'd love to upgrade from 2.x to 3.x, but we're currently blocked due to this issue.

brettsam commented 5 years ago

@davidmatson -- would you mind sharing a sample project file that's busted?

ghost commented 5 years ago

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment.

davidmatson commented 5 years ago

Program.cs:

using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

class Program
{
    static void Main()
    {
        new HostBuilder()
            .ConfigureLogging(b => b.AddConsole())
            .ConfigureWebJobs(b =>
            {
                b.AddAzureStorageCoreServices()
                .AddAzureStorage();
            })
            .Build()
            .Run();
    }
}

public static class Functions
{
    public static void ProcessMessage([QueueTrigger("test")] string message, [Blob("test/test")] out string blob)
    {
        blob = message;
    }
}

appSettings.json:

{
  "connectionStrings": {
    "azureWebJobsStorage": "AccountName=<name>;AccountKey=<key>"
  }
}

Two repro csproj's (normal-style with PackageReference, and new-style, more like Core/Standard):

Repro1.csproj (overall old project style but using PackageReference):

<?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>{AEF927C9-11E0-47B4-BCFD-8F4C573911F2}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <RootNamespace>TestWebJobs3x</RootNamespace>
    <AssemblyName>TestWebJobs3x</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>
    <Compile Include="Program.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config" />
    <None Include="appSettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.WebJobs">
      <Version>3.0.0</Version>
    </PackageReference>
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage">
      <Version>3.0.0</Version>
    </PackageReference>
    <PackageReference Include="Microsoft.Azure.WebJobs.Host.Storage">
      <Version>3.0.0</Version>
    </PackageReference>
    <PackageReference Include="Microsoft.Extensions.Logging.Console">
      <Version>2.1.0</Version>
    </PackageReference>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Repro2.csproj (new project style):

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net461</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.0" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.0" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Host.Storage" Version="3.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.0" />
  </ItemGroup>
  <ItemGroup>
    <None Update="appSettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>

Both projects show the same problem - at startup, this error appears:

warn: Host.Startup[0]
      Warning: Only got partial types from assembly: Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
      The following loader failures occured when trying to load the assembly:
         - Method 'Commit' in type 'Microsoft.Azure.WebJobs.Host.Blobs.Bindings.DelegatingCloudBlobStream' from assembly 'Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
         - Method 'Commit' in type 'Microsoft.Azure.WebJobs.Host.Blobs.Bindings.DelegatingCloudBlobStream' from assembly 'Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
         - Method 'Commit' in type 'Microsoft.Azure.WebJobs.Host.Blobs.Bindings.DelegatingCloudBlobStream' from assembly 'Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
         - Method 'Commit' in type 'Microsoft.Azure.WebJobs.Host.Blobs.Bindings.DelegatingCloudBlobStream' from assembly 'Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
         - Could not load type 'Microsoft.WindowsAzure.Storage.Table.TableQuerySegment' from assembly 'Microsoft.WindowsAzure.Storage, Version=9.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
      This can occur if the assemblies listed above are missing, outdated or mismatched.
      Exception message: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
         at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
         at System.Reflection.Assembly.GetTypes()
         at Microsoft.Azure.WebJobs.Host.Indexers.DefaultTypeLocator.FindTypes(Assembly assembly, IEnumerable`1 extensionAssemblies)

warn: Host.Startup[0]
      Warning: Only got partial types from assembly: Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
      The following loader failures occured when trying to load the assembly:
         - Method 'Commit' in type 'Microsoft.Azure.WebJobs.Host.Blobs.Bindings.DelegatingCloudBlobStream' from assembly 'Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
         - Method 'Commit' in type 'Microsoft.Azure.WebJobs.Host.Blobs.Bindings.DelegatingCloudBlobStream' from assembly 'Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
         - Method 'Commit' in type 'Microsoft.Azure.WebJobs.Host.Blobs.Bindings.DelegatingCloudBlobStream' from assembly 'Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
         - Method 'Commit' in type 'Microsoft.Azure.WebJobs.Host.Blobs.Bindings.DelegatingCloudBlobStream' from assembly 'Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
         - Could not load type 'Microsoft.WindowsAzure.Storage.Table.TableQuerySegment' from assembly 'Microsoft.WindowsAzure.Storage, Version=9.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
      This can occur if the assemblies listed above are missing, outdated or mismatched.
      Exception message: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
         at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
         at System.Reflection.Assembly.GetTypes()
         at Microsoft.Azure.WebJobs.Host.Indexers.DefaultTypeLocator.FindTypes(Assembly assembly, IEnumerable`1 extensionAssemblies)

And then when a message appears in the queue, processing fails with error (repeats until message is put in poison queue):

fail: Host.Results[0]
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessMessage ---> System.InvalidOperationException: Error while handling parameter blob after function returned: ---> System.TypeLoadException: Method 'Commit' in type 'Microsoft.Azure.WebJobs.Host.Blobs.Bindings.DelegatingCloudBlobStream' from assembly 'Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
   at Microsoft.Azure.WebJobs.Host.Blobs.Bindings.BlobsExtensionConfigProvider.CreateStreamAsync(BlobAttribute blobAttribute, ValueBindingContext context)
   at Microsoft.Azure.WebJobs.Host.Bindings.PatternMatcher.<>c__DisplayClass6_0`2.<<New>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.Azure.WebJobs.IConverterManagerExtensions.<>c__DisplayClass1_0`2.<<AsTyped>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.Azure.WebJobs.Host.Bindings.BindToStreamBindingProvider`1.StreamBinding.<>c__DisplayClass7_0.<<BuildAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.Azure.WebJobs.Host.Bindings.BindToStreamBindingProvider`1.BaseValueProvider.<GetOrCreateStreamAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.Azure.WebJobs.Host.Bindings.BindToStreamBindingProvider`1.OutArgBaseValueProvider`1.<SetValueAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ParameterHelper.<ProcessOutputParameters>d__32.MoveNext()
   --- End of inner exception stack trace ---
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ParameterHelper.<ProcessOutputParameters>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithWatchersAsync>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__17.MoveNext()
   --- End of inner exception stack trace ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<TryExecuteAsync>d__14.MoveNext()
fail: Function.ProcessMessage[0]
      Executed 'Functions.ProcessMessage' (Failed, Id=7086f4b7-0d98-4ee8-a145-97b68e081b7d)
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessMessage ---> System.InvalidOperationException: Error while handling parameter blob after function returned: ---> System.TypeLoadException: Method 'Commit' in type 'Microsoft.Azure.WebJobs.Host.Blobs.Bindings.DelegatingCloudBlobStream' from assembly 'Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
   at Microsoft.Azure.WebJobs.Host.Blobs.Bindings.BlobsExtensionConfigProvider.CreateStreamAsync(BlobAttribute blobAttribute, ValueBindingContext context)
   at Microsoft.Azure.WebJobs.Host.Bindings.PatternMatcher.<>c__DisplayClass6_0`2.<<New>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.Azure.WebJobs.IConverterManagerExtensions.<>c__DisplayClass1_0`2.<<AsTyped>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.Azure.WebJobs.Host.Bindings.BindToStreamBindingProvider`1.StreamBinding.<>c__DisplayClass7_0.<<BuildAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.Azure.WebJobs.Host.Bindings.BindToStreamBindingProvider`1.BaseValueProvider.<GetOrCreateStreamAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.Azure.WebJobs.Host.Bindings.BindToStreamBindingProvider`1.OutArgBaseValueProvider`1.<SetValueAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ParameterHelper.<ProcessOutputParameters>d__32.MoveNext()
   --- End of inner exception stack trace ---
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ParameterHelper.<ProcessOutputParameters>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithWatchersAsync>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__17.MoveNext()
   --- End of inner exception stack trace ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<TryExecuteAsync>d__14.MoveNext()

The same repro still occurs if I changed the projects to target .NET 4.7.2 instead of 4.6.1 and if I update all the NuGet package references to the latest available as of today.

Repro2updated.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net472</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.10" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.6" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Host.Storage" Version="3.0.8" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
  </ItemGroup>
  <ItemGroup>
    <None Update="appSettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>

Note that the startup error always occurs, but if the function doesn't use the affect type, I was able to get message processing to succeed.

ProgramPartlyWorkingSnippet.cs:

public static class Functions
{
    public static void ProcessMessage([QueueTrigger("test")] string message, ILogger logger)
    {
        logger.LogInformation(message);
    }
}
brettsam commented 4 years ago

Well, I completely missed following up on this -- @davidmatson do you know if you're still having this issue? If so we can take a look.

davidmatson commented 4 years ago

I'm not sure - I've switched to working on another project. If I recall correctly, the exception text still gets output but does not prevent loading, so I think it may be more spew and confusion than strictly blocking.

v-anvari commented 4 years ago

@brettsam , any thoughts here?

pragnagopa commented 4 years ago

@v-anvari - please try the repro and let us know if this is a blocker or not.