Search code examples
c#azureazure-webjobsepplusazure-webjobs-continuous

Web Job: Library not found


We have a continuous WebJob that is written in .NET Core 2.x and has been running fine for the past few weeks. Recently someone made some changes to this WebJob and brought in a 3rd party NuGet package. Now, I am unable to start the WebJob because it is unable to locate one of the 3rd Party libraries dependencies.

This is the error message:

D:\local\Temp\jobs\continuous\Temp1\oitdncff.sfg>dotnet Temp1.dll
Error:
An assembly specified in the application dependencies manifest (Temp1.deps.json) was not found:
package: 'System.Drawing.Common', version: '4.5.0-preview1-25914-04'
path: 'runtimes/win/lib/netcoreapp2.0/System.Drawing.Common.dll'

I have tried several things I found whilst Googling this problem. Here is the PropertyGroup and ItemGroup (NuGet packages) from the csproj file:

<PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <ApplicationIcon />
    <StartupObject>Temp1.Program</StartupObject>
    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
    <LangVersion>latest</LangVersion>
    <Version>1.0.0.0</Version>
    <PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>
<ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
    <PackageReference Include="AsyncEnumerator" Version="2.1.0" />
    <PackageReference Include="EPPlus.Core" Version="1.5.4" />
    <PackageReference Include="Microsoft.ApplicationInsights" Version="2.5.1" />
    <PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.5.1" />
    <PackageReference Include="Microsoft.Azure.ServiceBus" Version="2.0.0" />
    <PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.0-beta4" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Logging.ApplicationInsights" Version="3.0.0-beta4" />
    <PackageReference Include="Microsoft.Azure.WebJobs.ServiceBus" Version="3.0.0-beta4" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
    <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
</ItemGroup>

Per suggestions online, I added the line
<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
and
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />

The package in question that has the dependency is EPPlus.Core

I have confirmed that the library System.Drawing.Common does exist in the app folder on our Azure Web App but the when the WebJob starts up, it is ignoring that the file is there and looking in the runtimes (GAC) and failing.

UPDATE: I realized that the EPPlus.core package was not official so switched over to the official package hoping this would resolve the error. Same error but a new version of the System.Drawing.Common version: 4.5.0-preview1-26216-02

I have manually added the NuGet package for System.Drawing.Common version: 4.5.0-preview2-26406-04 to the project, this removed the original error but then I started getting an error that Microsoft.Win32.SystemEvents version: 4.5.0-preview2-26406-04 could not be found. This library is a dependent of System.Drawing.Common.

I attempted to do the same thing I did above and added the NuGet package for Microsoft.Win32.SystemEvents version: 4.5.0-preview2-26406-04 directly to the project but this time the error is not going away.

FURTHER UPDATE: After searching more, I came across a posting here that talked about publishing and then zipping up the published directory and uploading the zip. This did actually work, the error in question was gone but this is not really a solution. We are using VSTS as our repo system and our CI/CD. I have the build configration set to do a publish and then copy the files up. The WebJob throws the error when its deployed via this process.


Solution

  • First, I would like to state that as of today, to my knowledge, .NET Core is not 100% supported with Azure WebJobs (feel free to correct me if I am wrong) but there are lots of articles and posts on how to make them work.

    Below is the solution I did to get around the above issue I was having and whilst I do not feel this is elegant, I do feel that Microsoft has done something odd that most developers would not think is the correct path.

    The reason I was having issues was that when I built (in debug or release) the manifest file was always pointing to the runtimes (GAC). Running locally on my box was never an issue because the files could be found. The oddity is when building in release mode, all files were copied to the bin folder yet the manifest still told the program to look in the runtimes and not to use the local copies. When this was pushed out to the WebJob itself, these files did not exist in the runtime so the WebJob would throw exceptions.

    The workaround I had to do is as follows:

    1. dotnet build (Solution - Release Configuration)
    2. dotnet publish (WebJobs Only - Do Not Zip)
    3. dotnet publish (Web Project Only - Do Not Zip)
    4. Copy WebJob Data from Publish to the Web Project directory \App_Data\jobs\continuous\ directory
    5. Zip Up Web Project Published Directory (this is what gets deployed)

    My honest opinion is, when I build a webjob project in release mode, the process should transform the manifest to look for any referenced libraries locally before attempting to look for them in the runtimes.