Configuration preprocessor on mono

27 views
Skip to first unread message

Leszek Ciesielski

unread,
Sep 10, 2008, 9:18:59 AM9/10/08
to ccnet...@googlegroups.com
Hi,

I decided to update my copy+paste based config files to use templates
with the preprocessor. Unfortunately, as soon as I define a constant
and attempt to use it, ccnet.exe starts spilling out
NullPointerExceptions.

Config snippet (those are the only lines that I have changed):

<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<cb:define projectname="CashRegister.Mono"/>
<project name="$(projectname)">

Exception logged:

2008-09-10 15:12:43,687 [CCNet Server:INFO] Reading configuration file
"/home/cruisecontrol/CruiseControl.NET/server/ccnet.config"
2008-09-10 15:12:44,656 [CCNet Server:ERROR] INTERNAL ERROR: Object
reference not set to an instance of an object
----------
System.NullReferenceException: Object reference not set to an instance
of an object
at ThoughtWorks.CruiseControl.Core.Config.Preprocessor.ConfigPreprocessor.PreProcess
(System.Xml.XmlReader input, System.Xml.XmlWriter output,
ThoughtWorks.CruiseControl.Core.Config.Preprocessor.PreprocessorUrlResolver
resolver, System.Uri input_uri) [0x00000]
at ThoughtWorks.CruiseControl.Core.Config.DefaultConfigurationFileLoader.CreateXmlValidatingLoader
(System.IO.FileInfo configFile) [0x00000]
at ThoughtWorks.CruiseControl.Core.Config.DefaultConfigurationFileLoader.AttemptLoadConfiguration
(System.IO.FileInfo configFile) [0x00000]
at ThoughtWorks.CruiseControl.Core.Config.DefaultConfigurationFileLoader.LoadConfiguration
(System.IO.FileInfo configFile) [0x00000]
at ThoughtWorks.CruiseControl.Core.Config.DefaultConfigurationFileLoader.Load
(System.IO.FileInfo configFile) [0x00000]
at ThoughtWorks.CruiseControl.Core.Config.FileConfigurationService.Load
() [0x00000]
at ThoughtWorks.CruiseControl.Core.Config.FileWatcherConfigurationService.Load
() [0x00000]
at ThoughtWorks.CruiseControl.Core.Config.CachingConfigurationService.Load
() [0x00000]
at ThoughtWorks.CruiseControl.Core.CruiseServer..ctor
(IConfigurationService configurationService,
IProjectIntegratorListFactory projectIntegratorListFactory,
IProjectSerializer projectSerializer) [0x00000]
at ThoughtWorks.CruiseControl.Core.CruiseServerFactory.CreateLocal
(System.String configFile) [0x00000]
at ThoughtWorks.CruiseControl.Core.CruiseServerFactory.CreateRemote
(System.String configFile) [0x00000]
at ThoughtWorks.CruiseControl.Core.CruiseServerFactory.Create
(Boolean remote, System.String configFile) [0x00000]
at ThoughtWorks.CruiseControl.Core.ConsoleRunner.LaunchServer () [0x00000]
at ThoughtWorks.CruiseControl.Core.ConsoleRunner.Run () [0x00000]
at ThoughtWorks.CruiseControl.Console.ConsoleMain.Main
(System.String[] args) [0x00000]
----------

This is using mono 1.9.1, CruiseControl.Net 1.4.0.3570 (release). Am
I doing something wrong?

Regards,

Leszek 'skolima' Ciesielski

Daniel Hommel

unread,
Sep 10, 2008, 9:40:43 AM9/10/08
to ccnet...@googlegroups.com
Hi Leszek,

this problem was mentioned on the user list a some weeks ago. I tried to
do a debug build on mono to get this .mdb files but i failed. Without
the .mdb files i can't use the mono debugger and so it is hard for me to
find the source of the NullReferenceException. Maybe you know how to do
a debug build on mono?

As far as i know the gmcs compiler is for the .NET 2.0 and 3.0 profile
but it complains about the ConfigurationManager class. I have no idea
how i can get around this problem. Any ideas?

regards,

Daniel

Leszek Ciesielski

unread,
Sep 10, 2008, 12:11:03 PM9/10/08
to ccnet...@googlegroups.com
I'll look into it tomorrow, I hoped it was perhaps my mistake, not
mono-related problem...

gmcs supports 2.0, 3.0 and 3.5 profiles (although not all class
library API is present).

How did you compile CCNet with mono (I know monodevelop can supposedly
handle .csproj files but I have never actually tried this).?

--
MS-DOS user since 5.0
Windows user since 3.11
Linux user since kernel 2.4
Novell Netware user since 2.2
WARCRAFT user since 1.0

Daniel Hommel

unread,
Sep 10, 2008, 1:29:46 PM9/10/08
to ccnet...@googlegroups.com
Leszek Ciesielski wrote:
> I'll look into it tomorrow, I hoped it was perhaps my mistake, not
> mono-related problem...
>
> gmcs supports 2.0, 3.0 and 3.5 profiles (although not all class
> library API is present).
>
> How did you compile CCNet with mono (I know monodevelop can supposedly
> handle .csproj files but I have never actually tried this).?

I tried XBuild and your compile.byhand Nant target that i found on the
lists. :-) Seems a bit outdated and i didn't have the time to get it to
work again... I've read something about building MS format projects with
monodevelop but i thought that's a planned feature for 2.0 or something.
I can try to build using monodevelop but i guess it will just use XBuild?

I really wonder why the ConfigurationManager class seems not to be
present in my mono installation, and if i patch the code to use
ConfigurationSettings i get a warning i should use ConfigurationManager
instead... And the ConfigurationManager class is mentioned on the mono
lists so i think it should exist? Maybe i just failed to add all needed
references or so...

regards,

Daniel

Alex

unread,
Sep 10, 2008, 9:33:05 PM9/10/08
to ccnet-devel
Just to add something here, even though I am also having a lot of
issues with Mono on Mac OSX is that MonoDevelop GUI will open and use
the ccnet.sln file. It is extremely easy to compile, debugging is
another issue.

On Sep 10, 1:29 pm, Daniel Hommel <daniel.hom...@it-designers.de>
wrote:
> >>>   at ThoughtWorks.CruiseControl.Core.Config.Preprocessor.ConfigPreprocessor.PreP­rocess
> >>> (System.Xml.XmlReader input, System.Xml.XmlWriter output,
> >>> ThoughtWorks.CruiseControl.Core.Config.Preprocessor.PreprocessorUrlResolver
> >>> resolver, System.Uri input_uri) [0x00000]
> >>>   at ThoughtWorks.CruiseControl.Core.Config.DefaultConfigurationFileLoader.Creat­eXmlValidatingLoader
> >>> (System.IO.FileInfo configFile) [0x00000]
> >>>   at ThoughtWorks.CruiseControl.Core.Config.DefaultConfigurationFileLoader.Attem­ptLoadConfiguration
> >>> (System.IO.FileInfo configFile) [0x00000]
> >>>   at ThoughtWorks.CruiseControl.Core.Config.DefaultConfigurationFileLoader.LoadC­onfiguration
> >>> Leszek 'skolima' Ciesielski- Hide quoted text -
>
> - Show quoted text -

Leszek Ciesielski

unread,
Sep 11, 2008, 6:48:33 AM9/11/08
to ccnet...@googlegroups.com
Compiling CruiseControl.Net on Linux: launch MonoDevelop, open
ccnet.sln, remove CCTrayLib, CCtray and UnitTests projects (CCTrayLib
depends on COM and is full of windoisms, it won't compile on Linux),
compile. Binaries are located in project/console/bin/Debug. This is
also doable from command line, just edit ccnet.sln to remove the three
projects and launch 'mdtool build -f:ccnet.sln'.

The stack trace with line numbers is attached (to get this you need to
have .mdb files in same place as assemblies and launch mono with
--debug).

Regards,

Leszek 'skolima' Ciesielski

ccnet.log

Jeremy Lew

unread,
Sep 11, 2008, 9:50:40 AM9/11/08
to ccnet...@googlegroups.com
I see the problem. The code is using a well-known but hacky trick to
rethrow an exception while preserving the stack trace, which is apparently
implemented differently on Mono. If you simply comment out the two lines:

79 if ( ex.InnerException != null )
80 {
81 // Get the _remoteStackTraceString of the
Exception class
82 FieldInfo remoteStackTraceString =
typeof(Exception).GetField("_remoteStackTraceString",
83 BindingFlags.Instance | BindingFlags.NonPublic );
84
85 // Set the InnerException._remoteStackTraceString
to the current InnerException.StackTrace
86 remoteStackTraceString.SetValue(
ex.InnerException,
87 ex.InnerException.StackTrace + Environment.NewLine
);
88 // Throw the new exception
89 throw ex.InnerException;
90 }
91 throw;

If you comment out lines 83-87, things ought to work fine. Is there a way
to detect the Mono compiler via an #if statement to conditionally compile
this?

Leszek Ciesielski

unread,
Sep 11, 2008, 10:09:10 AM9/11/08
to ccnet...@googlegroups.com
Compilation-time is not a good idea, I am using MS.Net produced
binaries on Linux and I know other people are doing the same. If you
really need to, detection is better performed at runtime:

public static bool IsRunningOnMono ()
{
return Type.GetType ("Mono.Runtime") != null;
}

However before this hack goes in, I'd like to verify this is still a
problem with Mono 2.0 (and fill a bug report if it is).

--

Leszek Ciesielski

unread,
Sep 11, 2008, 11:04:14 AM9/11/08
to ccnet...@googlegroups.com
In mono this internal field is named "remote_stack_trace" instead of
"_remoteStackTraceString". I'll file a bug about it, because there
probably are other programs using this hack (it has a lot of hits on
google...), but even if this is changed there is no chance of getting
this backported to Mono 2.0 (which should be released this September
29th), so this won't change before 2.2 (November).

For now the best way of handling this would be checking which one of
the two field exists before using it.

Leszek Ciesielski

unread,
Sep 11, 2008, 3:39:35 PM9/11/08
to ccnet...@googlegroups.com
Bug filled with Mono (not sure if it gets fixed, it's a really corner
case, private fields are not part of the API :-) )

Most optimal workaround would be:

FieldInfo remoteStackTraceString =
typeof(Exception).GetField("_remoteStackTraceString",

BindingFlags.Instance | BindingFlags.NonPublic); // MS.Net

if (remoteStackTraceString == null)
remoteStackTraceString = typeof(Exception).GetField("remote_stack_trace",
BindingFlags.Instance | BindingFlags.NonPublic); // Mono

as this will work even if Mono changes it's behaviour and does not
slow code on MS.Net in any way.

Daniel Hommel

unread,
Sep 11, 2008, 6:21:27 PM9/11/08
to ccnet...@googlegroups.com
I've opened CCNET-1244 for this problem and committed the proposed
workaround. Please verify that build 1.4.0.3659 (revision 4135) is
working on Mono.

regards,

Daniel

Leszek Ciesielski

unread,
Sep 12, 2008, 2:38:45 AM9/12/08
to ccnet...@googlegroups.com
Running this build right now. The first problem (NRE) is fixed, I am
getting the actual exception now. I don't know yet what to do with
that, will look into the code a bit later today. Log snippet attached
(I am quite sure that projectname is actually defined, my config
sample is included in the first post in this thread).
ccnet.log

Leszek Ciesielski

unread,
Sep 12, 2008, 3:01:12 AM9/12/08
to ccnet...@googlegroups.com
Once again the log, this time with debug symbols for CC.Net in place.
ccnet.log
Reply all
Reply to author
Forward
0 new messages