[.NET Core] 문제 해결: An assembly specified in the application dependencies manifest was not found:

뜬금없이 발생한 문제

밤을 새고 12시에 깨서, 배탈이 나서 화장실로 리다이렉트된 뒤 컴퓨터에 앉아 업무용 디스코드 서버를 들어가니 오늘도 역시 버그 제보가 올라와 있었습니다.
헌데, 이번 문제는 좀 특이했습니다. 240대의 동일한 환경의 컴퓨터 중 단 2대에서 문제가 발생한 것이죠.

디버깅

버그 제보에는 응용 프로그램이 실행되지 않는다고 올라옴과 동시에, 잘 되는 컴퓨터에서 통채로 복사해도 여전히 실행되지 않는다는 내용이 추가로 쓰여있었습니다. 여기서 직감적으로 느꼈습니다. 아. 이거 디펜던시 문제구나.
하지만, 정확히 어디서 문제가 생겼는지는 직접 확인해봐야 했기에, 원격으로 해당 컴퓨터에 접속해 문제를 파악하기 시작했습니다.
우선, 프로그램을 실행했습니다. 문제 없이 실행되는 것처럼 보였으나, 잠시 후 업데이트 단계에서 프로그램이 예고없이 종료되었습니다. 로그를 확인해봐도 프로그램 자체는 정상적으로 업데이터까지 실행했다고 나와있었고요.
그래서, 이번엔 업데이터를 수동으로 실행해봤습니다. 아직까지는 UI가 없는 콘솔 형태의 업데이터인지라, 프로그램이 꺼짐과 동시에 콘솔이 날아가버리는 것을 방지하기 위해 명령 프롬프트에서 실행했죠.
그랬더니 다음과 같은 에러가 보이더군요.
An assembly specified in the application dependencies manifest (####.deps.json) was not found:
여기서 의심은 확신이 되었습니다.

구글링

의심이 확신이 된 것까진 좋은데, 어떻게 해결해야 할지는 바로 감이 오지 않는 상황이었습니다. 위 업데이터는 태어나서 처음으로 .NET Core 어플리케이션을 Publish, 그것도 단일 파일로 퍼블리시한 상태이기 때문에 도대체 어디서 문제가 생긴 것인지 알 수가 없었기 때문이죠.
하지만 당연히 문제가 될 것은 없습니다. 왜냐하면 저, 그리고 여러분에겐 구글과 스택오버플로우가 있기 때문입니다. 검색을 진행했죠.
키워드: An assembly specified in the application dependencies manifest was not found:
바로 첫 번째 검색 결과에 답이 나오더군요. 바로 이 스택오버플로우 글입니다.
해당 글의 답변에 따르면, 일반적으로 개발 머신에는 SDK가 설치되지만 배포 환경에서는 런타임 디펜던시만 설치된다며 csproj 파일에 다음과 같은 엘리먼트를 추가하라고 합니다.
<PropertyGroup>
    <PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>

문제는 해결됐다. 그런데 도대체 어떻게 된 것일까?

개발자라면 누구나 한 번 쯤 봤을 법한 유명한 짤이 하나 있죠.
It Doesn't Work Why? It Works Why? We knowMemes | Work Meme on ME.ME
왜? 도대체 왜 되는거지?
XML 요소의 이름에서 대충 배포시 ASP.NET Core 타겟 매니페스트를 포함하지 않겠다 정도까지는 유추할 수 있습니다. 그러나, 애초에 문제가 생긴 어플리케이션은 ASP.NET Core가 아닌, .NET Core 콘솔 응용 프로그램이었습니다.
그럼 뭐 별 수 있나요? 구글링 해야죠. 문제는 단순히 PublishWithAspNetCoreTargetManifest 키워드로 검색을 할 경우에는 스택오버플로우와 같은 사이트들만 나타나고, 정의가 어떻게 되는지에 대해서는 나오지 않았습니다. 그래서 PublishWithAspNetCoreTargetManifest MSDN이라고 검색하니 납득이 갈만한 MSDN 문서가 나왔습니다.
해당 문서의 마지막 부분을 보면 다음과 같은 문구가 있습니다.
When deploying a runtime-dependent deployment app, make sure that the target environment has the .NET Core SDK installed. If the app is deployed to an environment that doesn’t include ASP.NET Core, you can opt out of the implicit store by specifying <PublishWithAspNetCoreTargetManifest> set to false in the project file as in the following example:
런타임 의존 앱을 배포할 때에는 해당 환경에 .NET Core SDK가 설치되어 있어야 한다. 만약 배포 환경이 ASP.NET Core를 포함하지 않는다면, 프로젝트 파일의 <PublishWithAspNetCoreTargetManifest> 요소를 false로 설정해 암시적 저장소를 제외시킬 수 있다.
단순 번역으로는 무슨 소리인지 모르겠네요. 하지만 그 밑에 예문에 정답이 나와있었습니다.
Note
For self-contained deployment apps, it’s assumed that the target system doesn’t necessarily contain the required manifest packages. Therefore, <PublishWithAspNetCoreTargetManifest> cannot be set to true for an self-contained app.
단일 포함 앱을 배포할 경우에는 배포 환경에 필요한 매니페스트 패키지가 없을 것으로 가정하므로, 이 때에는 <PublishWithAspNetCoreTargetManifest>가 true로 설정되면 안 된다는 얘기입니다.
흠… 좋아요. 여기까진 이해했습니다. 그러나 아직도 이해가 되지 않는 것이 하나 있죠. 바로 저는 ASP.NET Core가 아닌, .NET Core 콘솔 앱을 만들어 게시를 사용해 배포했는데 도대체 왜 이러한 문제가 생겼는가? 입니다.
정답인지는 아직도 모르겠지만, 유추해보기로 아마 ASP.NET에서 사용되는 일부 라이브러리(Microsoft.Extensions.Configuration.Bindings 등등)를 사용해서가 아닐까 싶습니다.

결론

단일 파일 배포시 프로젝트 파일의 <PublishWithAspNetCoreTargetManifest>를 false로 설정하면 문제는 해결됩니다. 다만, 애초에 VS2019의 퍼블리싱 기능을 사용해 단일 파일 옵션을 체크하고 배포한 것인데, 알아서 좀 false로 설정됐으면 좋으련만 굳이 수동으로 설정해야 한다는 점이 아쉬울 뿐입니다.

댓글

이 블로그의 인기 게시물

C# 남아도는 메모리에도 불구하고 OutOfMemoryException이 발생한다면?

MySQL 데이터 타입과 Java 데이터 타입 비교/매칭

테일즈위버 OST 전곡 모음