Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`Unhandled Exception: System.ArgumentNullException: Value cannot be null.` error while running `dotnet run` using a startup script

I'm trying to run a dotnet app using dotnet run --configuration Release at system server Startup/Reboot. I'm using a init.d script to acheive the same.

My startup script, located at /etc/init.d/myscript contains the following:

#!/bin/sh
/home/user/myscripts/botScript.sh

Contents of botScript.sh:

#!/bin/bash
cd /home/user/bot/
nohup dotnet run --configuration Release &

When my server Starts or Reboots the startup script gets executed but dotnet run doesn't work. I get the following error(s):

Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: path1
   at System.IO.Path.Combine(String path1, String path2, String path3)
   at Microsoft.DotNet.ProjectModel.Resolution.PackageDependencyProvider.ResolvePackagesPath(String rootDirectory, GlobalSettings settings)
   at Microsoft.DotNet.Configurer.NuGetCacheSentinel.get_NuGetCachePath()
   at Microsoft.DotNet.Configurer.NuGetCacheSentinel.Exists()
   at Microsoft.DotNet.Configurer.DotnetFirstTimeUseConfigurer.ShouldPrimeNugetCache()
   at Microsoft.DotNet.Configurer.DotnetFirstTimeUseConfigurer.Configure()
   at Microsoft.DotNet.Cli.Program.ConfigureDotNetForFirstTimeUse(INuGetCacheSentinel nugetCacheSentinel)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
   at Microsoft.DotNet.Cli.Program.Main(String[] args)

But all other commands works fine in that script & even simply running dotnet works fine too (I have checked that). It's just that dotnet run doesn't work.

Yeah, but when I run the scripts, both myscript as well as botScript.sh, after loging in to my server, it works fine without any errors.

Please, can anyone help me out on this?

like image 264
The Gamer Foundation Avatar asked Nov 26 '16 08:11

The Gamer Foundation


2 Answers

There's obviously a bug in PackageDependencyResolver, but to find a workaround, consider the order in which the packages folder is found:

  1. global.json { "packages": "..." }
  2. NUGET_PACKAGES environment variable.
  3. {DefaultLocalRuntimeHomeDir}\packages

Your code is falling all the way to case #3 above. To work around this, create an environment variable called NUGET_PACKAGES pointing to you packages folder. For example, in botScript.sh:

#!/bin/bash
cd /home/user/bot/
export NUGET_PACKAGES="/home/user/.nuget/packages" # <=== 
nohup dotnet run --configuration Release &

For more info, see PackageDependencyResolver.cs and PackageDependencyResolver.cs

like image 171
Diego Avatar answered Oct 04 '22 04:10

Diego


Don't run dotnet with root user

If it runs from init.d, it is invoked with root user. Running program with root will expose your machine to severe security issues, especially with .net core which is still under heavy development and so is not security hardened yet.

Run a service with specific user

Your error is probably cause by the fact that for root no packages directory is defined, however when you run it manually, it is with your user which has /home/user/.nuget/packages directory defined.

  • From asp.net core documentation, you can setup a service and specify a user which will run dotnet
  • Just use su command to run dotnet with the specified user

Supervisor users

Here an extract of supervisor conf for my own site

/etc/supervisor/conf.d/mysite.conf:

[program:mysite]
command=/usr/bin/dotnet /var/www/mysite/MySite.dll
directory=/var/www/mysite
autostart=true
autorestart=true
stderr_logfile=/var/log/mysite.err.log
stdout_logfile=/var/log/mysite.out.log
environment=ASPNETCORE_ENVIRONMENT=Production
user=www-data <=== SPECIFY A USER HERE
stopsignal=INT

Don't use dotnet run outside of development/debugging purpose

As dotnet --help says, the run command compiles and executes a project.

run           Compiles and immediately executes a .NET project

Compilation wil require additional steps, and then computing power and so additional time (each time it is run, even there is no changes in code). It wil also requires restore and build to work (which requires a normal developer user). It is also more failure prone because of the additional steps that could fail.

Instead run compilation once with your developer user and then run your program with a service user like www-data (which is kind of builtin user for websites)

dotnet MyCompiledAssembly.dll
like image 30
Fab Avatar answered Oct 04 '22 02:10

Fab