C# & VB.NET2008.03.13 13:14

가끔 우리 솔루션에서는 System.Runtime.Serialization.SerializationException이 발생한다. 문제가 발생한 상황이니까 예외가 던져지는 것은 당연하다. 하지만 문제는 실제 에러는 SerializationException이 아니라는 것이었다. 그리고 SerializationException은 다들 알다시피 객체가 Serialization/Deserialization하는 과정에서 나는 문제인데, 이 에러가 날만한 시나리오를 딱히 생각해낼 수는 없었다.

Stacktrace를 보니 이 예외는 솔루션 내부의 로깅 컴포넌트에서 던져지고 있었다. 로깅 컴포넌트는 에러나 문제가 발생했을 때 그 정보를 파일에 기록하는 역할을 하는 COM+ 서버 타입 컴포넌트였다. 문제가 생긴 함수는 다음과 같았다.

Public Function WriteException(ByVal userName as string, ByVal exception as System.Exception) as string

 
이 함수는 Exception객체를 받아서 그 예외 정보를 포맷한 뒤 파일에 쓰는 함수였다. 여기서 문제가 될만한 부분은 인자로 System.Exception 객체를 받는 부분뿐이었는데, 로깅 컴포넌트가 COM+ 서버 타입이기 때문에 Exception객체가 프로세스간 이동을 하기 때문이었다. 하지만 System.Exception 객체가 Serialization 과정에서 문제가 생긴다는 것은 사실 상상하기가 힘들었는데..
 
암튼 조사 끝에 이유를 알아내었다. 문제가 생긴 객체는 모두 System.Web.HttpException이었다. 그리고 이 System.Web.HttpException이 무슨 이유인지는 몰라도, .NET Framework 1.1에서는 Serializable로 마킹이 되어 있지 않다는 사실을 알게 되었다. 즉 Logging컴포넌트에서 HttpException을 인자로 받았는데, 이게 COM+ 서버 타입이라 프로세스 이동을 하려면 Serialization과정을 거치다가.. Serializable 마킹이 안 되어 있어서 Serialization작업을 못한 것이다. 그래서 SerializationException도 났던 것이고..
 
.NET 1.1과 2.0의 System.Web.HttpException을 Reflector로 열어보면 다음과 같다.
 
1.1의 경우
DotNet1HttpException
 
2.0의 경우
DotNet2HttpException
 
.NET Framework 2.0에서는 Serializable 어트리뷰트가 있지만, .NET Framework 1.1에서는 없는 것을 볼 수 있다. 왜 1.1에서 없는지는 속시원한 설명을 제대로 찾지 못했다. 현재로서는 버그가 아닐까 추측만 될 뿐이다. 그리고 2.0이상부터는 이런 문제가 없는 것 같다.
 
우리 솔루션은 로깅 컴포넌트의 COM+ 유형을 Server Type에서 Library Type 으로 바꾸어서 해결했다. Library Type이라면 프로세스가 다르지 않을테고 프로세스간 객체 이동도 없을 것이니, 이 문제를 신경쓰지 않아도 되는 것이다.
 
다른 곳에도 이 케이스처럼 Exception객체가 프로세스를 넘어가는 시나리오가 있다면, 이 문제를 조심해야 할 것이다.
신고
Posted by kkongchi

티스토리 툴바