Wednesday, February 10, 2010

Using .NET 3.5 (CLR 2.0) DLL inside Visual Studio 2010 for a .NET 4.0 Project/Application

When you first create a .NET 4.0 project inside VS 2010 and add reference to a .NET 3.5 DLL (say log4net or Rhino.Mocks), the project tends to not build. You can get errors as shown below.

image

It might appear to be a CLR version issue – unable to run 2.0 DLL inside a 4.0 App Domain. And i thought that is what it was until now.

You can get over this :)

By default, VS 2010 creates the projects with Target Framework on the properties set to “.NET Framework 4 Client Profile”. You would have to change that to “.NET Framework 4” by going to Project Properties –> Application –>  Target Framework. And every thing begins to compile.

So I guess, one has to be aware of this when migrating old solutions from Visual Studio 2008 to Visual Studio 2010.

Proof that it works :) Notice the .NET Framework 4.0 features as well Log4Net and Rhino.Mocks used in all the same example. (It is a stupid example, but the intention was to show it works).

image

If for some reason, it does not work for you, try to add

<?xml version ="1.0"?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
     <supportedRuntime version="v2.0.5727" /> 
    <supportedRuntime version="v4.0.21006"/>
  </startup>
</configuration>

to your csc.exe.config/msbuild.exe.config/VCSExpress.exe.config/devenv.exe.config …

I initially thought it has something to do with not enabling Side-By-Side Execution of the  compiler and stuff but it turns out that it is not the case. For your information,  i have added supported runtime as .NET 2.0 but then commented it to be sure that its ONLY the Target Framework that has to be changed.

Thursday, February 04, 2010

Breaking my head with message passing and Scala Actors

I recently started working on a personal project on which a friend of mine is helping. After some discussion, we thought Scala might be a good bet to use as the development platform of our choice (and we integrate Spring into Scala). Anyway for that, I got into Scala actors. Actors appear easy code – all you have to do is create an actor (if you use Actor.actor construct, it starts automatically, otherwise you have to invoke start) and from somewhere keep sending messages to the Actor.

So let us first define what message that I want to send using Case Classes. Refer the documentation on case classes.


case class Message(someData : String)


Now let us create our component which is an Actor and for each string passed in the constructor, we append the message (Some stupid behavior, but serves the example here)




class MyActor(toInform: Array[String]) extends scala.actors.Actor{
private val noticeTo = toInform
def act(){
loop{
react{
case Message(r) =>{
for(item<-noticeTo)
println(item+"_"+r)
}
}
}
}
}


Now with the following code to test the above actor




val actor = new MyActor(Array("Krishna"))
actor ! "Welcome"


With all the excitement in the world, you run the test and it just hangs in there, nothing happens :). So you suddenly realize "YOU FORGOT TO START THE ACTOR". Damn! it was the actor.start that is causing the issue. So you cleverly add the actor.start statement. ("you" meaning "me")




val actor = new MyActor(Array("Krishna"))
actor.start //do not forget this :)
actor ! "Welcome"


You run the test again, to have no success. Then you realize that your actor expects Message(r) where as you are sending a String. So you change that




val actor = new MyActor(Array("Krishna"))
actor.start //do not forget this :)
actor ! Message("Welcome")
//actor.exit


Also notice the commented out explicit kill of the exit call outside the actor. It is not advised to be doing that. Remeber that "!" is a send-and-continue kinda call (asynchronous call). So before the actor is scheduled to work on the message, it might be killed. Instead it is advised that you specify an "Exit" like message within the case on the Actor. Now you run the test and it works :) Hurray!!!!



Later, smart-ass like you (this time, it is you :)), decide to write a very bad code (ok, you is not really you, for now lets assume the actor code i wrote is simply perfect) like shown below.




object Launcher extends Application{
val actor = new MyActor(null)
actor start() //do not forget this
actor ! Message("Welcome")
actor ! "E" //this is the exit message.
}


You repeat the test again :) and this time it does nothing, it appears to be blocked :). Again....damn... so how would we know what the issue is? You spend a your day-off trying to figure out what is wrong with this simple code...then after spending 10 hours trying all the magic tricks (aparently, i know too many magic tricks that never work, hence the time), you realize the actor must be dead (netbeans threads view would show what threads are running and you never see any FJ Threads). So the actor died! So what can kill an actor? - call to exit(), or an exception!!!! There it is .. so let us change the actor code so that it can catch the exception.




class MyActor(toInform: Array[String]) extends scala.actors.Actor{
private val noticeTo = toInform
def act(){
loop{
react{
case Message(r) =>{
try{
for(item<-noticeTo)
println(item+"_"+r)
}catch{
case e => e.printStackTrace
}
}
case "E" => exit
}
}
}
}


Run the test again and notice the stacktrace!




java.lang.NullPointerException
at scala.collection.mutable.ArrayOps$ofRef.length(ArrayOps.scala:68)
at scala.collection.IndexedSeqLike$class.foreach(IndexedSeqLike.scala:86)
at scala.collection.mutable.ArrayOps.foreach(ArrayOps.scala:20)
at tryscala.MyActor$$anonfun$act$1$$anonfun$apply$1.apply(Launcher.scala:13)
at tryscala.MyActor$$anonfun$act$1$$anonfun$apply$1.apply(Launcher.scala:10)
at scala.actors.Reaction$$anonfun$$init$$1.apply(Reaction.scala:33)
at scala.actors.Reaction$$anonfun$$init$$1.apply(Reaction.scala:29)
at scala.actors.ReactorTask.run(ReactorTask.scala:33)
at scala.actors.scheduler.ForkJoinScheduler$$anon$1.compute(ForkJoinScheduler.scala:111)
at scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:147)
at scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)
BUILD SUCCESSFUL (total time: 7 seconds)


So the fix is to :) pass in an empty array at least, instead of sending in a null ( use Array.empty).



Clearly, this is not the exact sample that I was running, it was a little bit complicated and myself being totally new to Scala had a hard time trying to figure out that an exception can kill scala Actors!!! I know I am dumb, but with this post, I want to save you from considering yourself dumb after trying very hard for a few hours.