I’m trying to deploy my first AppHarbor-hosted app and have run into a problem with my build. Everything builds fine until the code contracts try to rewrite the assemblies. The error in the log is:
CodeContractsRunCodeAnalysisInternal:
CodeContracts: Task manager is unavailable (unable to run in background).
CodeContracts: ABC: Run static contract analysis.
CodeContracts: ABC: Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'System.Data.SqlServerCe, Version=3.5.1.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot find the file specified.
CodeContracts: ABC: at Microsoft.Research.CodeAnalysis.SQLCacheDataAccessor.GetMetadataOrNull(String key, Boolean silent)
CodeContracts: ABC: at Microsoft.Research.CodeAnalysis.CacheManager`11.TestCache()
CodeContracts: ABC: at Microsoft.Research.CodeAnalysis.CacheManager`11..ctor(Dictionary`2 methodAnalyses, Dictionary`2 classAnalyses, GeneralOptions options)
CodeContracts: ABC: at Microsoft.Research.CodeAnalysis.CacheManager`11.Create(Dictionary`2 dictionary, Dictionary`2 dictionary_2, GeneralOptions generalOptions)
CodeContracts: ABC: at Microsoft.Research.CodeAnalysis.Clousot.TypeBinder`9..ctor(String[] args, IDecodeMetaData`9 mdDecoder, IDecodeContracts`5 contractDecoder, IDictionary assemblyCache, Action`3 setTargetPlatform, IOutputFullResultsFactory`2 externalOutputFactory)
CodeContracts: ABC: at Microsoft.Research.CodeAnalysis.Clousot.ClousotMain[Local,Parameter,Method,Field,Property,Event,Type,Attribute,Assembly](String[] args, IDecodeMetaData`9 mdDecoder, IDecodeContracts`5 contractDecoder, IDictionary assemblyCache, Action`3 setTargetPlatform)
CodeContracts: ABC: at Microsoft.Research.CodeAnalysis.CCI1Driver.Main(String[] args)
CodeContracts: ABC:
CodeContracts: ABC: Static contract analysis done.
I know that when building locally with Visual Studio that the code contract stuff runs in a background thread. Maybe AppHarbor does not allow such threads to be created to do this? But what is this error about System.Data.SqlServerCe.dll missing? My code sure doesn’t use it but maybe the MS code contracts do?
Just wondering if anyone has successfully deployed code that has code contracts in it to AppHarbor and if so what did you do to make it work? It may be that SQL Server CE will need to be installed by AppHarbor in order for code contracts to work. Oh, and my build does not build the code contract reference assembly, it just tries to do the static checking and do the rewriting to get the run-time checks done.
Lastly, I did try disabling the code contracts from the AppHarbor.sln but that setting is a project setting and not a solution setting so it disables them for my regular solution file too.
Figured it out. The .NET Code Contracts (the System.Diagnostics.Contracts namespace, for those who don’t know) has a feature that can do static analysis of the code based on the contracts that have been put into the code. If you have the Visual Studio add-on for code contracts installed you can go to a VS project’s property pages and click the Code Contract tab. In the Static Checking section there is an option called Cache Results. If you enable this then the static checking uses a SQL Server embedded database at build time to make whatever it does for its static code analysis run faster (apparently this file will persist in your project directory between compiles). This is a dependency that a build server has on SQL CE, it has nothing to do with the run-time environment for the app.
Since AppHarbor does not have SQL CE on their build servers what I’ve done is to change each of my projects’ Code Contracts properties to do Perform Runtime Contract Checking and Perform Static Contract Checking for both Debug and Release builds, but for the Release build the Cache Results option in the Perform Static Contract Checking section is disabled. (Note also that since AppHarbor doesn’t allow background tasks to run from Visual Studio that the Check in Background option on the Perform Static Contract Checking section must also be disabled.)
Why does it seem like I’m the only one that uses the System.Diagnostics.Contracts namespace (other than the .NET Framework itself)?