The Irony of All Ironies: Memory Leak in .NET CLR

June 10th, 2008

So I started using my super-mega-awesome BizTalk dynamic map in one of my projects, and one of the minions from the Operations group reported that my BizTalk application has been hovering at 1.5GB of memory usage since it was installed and still growing…he got all cocky and said that the application probably has a memory leak.

Of course, just like any .NET developer would respond: I laughed it off and said “.NET can’t have memory leaks…that would be too ironic.”

When I came to my senses, I realized…yes, with .NET you can forget about application memory managment…in theory. Then I remember the whole “the-intarwebs-is-collapsing” news when a release of Java that has a memory leak. So I googled “.NET XSLT memory leak” just to try to have an open mind.

Well, whaddayaknow, Google pointed me to this KB Article. It says it only applies to .NET 1.0…Oh that’s a big lie; it appies to .NET 2.x as well.
I fixed the code and I thought about updating the code on dynamic BizTalk maps. But I’m too lazy. Suck it.

I leave this nifty Powershell one-liner for checking the Memory usage status of BizTalk app…….here I played with the simple tasklist application…which for some bizarre reason doesn’t allow /svc and /v to be used at the same time…so I came up with this:

tasklist /fi “`”PID eq $((tasklist /svc /nh /fi ‘SERVICES eq BTSSvc$YOUR_BIZTALK_APPL_NAME_LOL’)[1].Split(’ ‘, [StringSplitOptions]::RemoveEmptyEntries)[1])`”"

BizTalk PowerShell Adapter

May 16th, 2008

I just finished an implementation of BizTalk PowerShell Adapter. Right now, it only supports Send Ports, but of course this can be modified to support Receive Locations as well.

Basically, when you create the Send Port, you point the location of the .ps1 file and that file gets executed for each message. Of course, that’s useless if you can’t get the message itself…so…in your PS script, you will have access to a variable $BizTalkMessage which contains the context, data, and config .NET objects.

Attached is the zip file for the source, registry file and sample powershell script. I only tested this on BizTalk 2006, but I believe this should also work with BizTalk 2004.
I couldn’t have done this without this information. Credits to Mr. Mikkers.

Powershell BizTalk 2006 Adapter

The REAL Dynamic BizTalk Mapping/Transform

May 8th, 2008

It’s been a long while since I wrote something meaningful about programming anything. The last few entries are mostly rants and complaints that probably gives an impression that I stopped programming altogether. On the contrary, I actually still do a lot of programming, it’s just that the code I write is pretty much plain-vanilla and is not even worth mentioning in a conversation with a fellow BizTalk developer…let alone a blog that anyone else can read.

Anyhoo…before I bore my three readers to death with nonsense. I present my proudest contribution to the world of BizTalk programming: REAL Dynamic BizTalk Mapping/Transform. Why do I have to stress out that REAL part? Well, let me give you a background on this…

Prior to BizTalk 2004, Maps (Transform Objects) are hosted in an IIS server and BizTalk pulls the Transform object at runtime. This sucks because you need IIS..but it rules at the same time because you don’t need to recompile everytime you need changes to your map.

Now, fast-forward to today’s BizTalk: I guess some numbnut over at Microsoft thought it was a good idea to “compile” the map into your BizTalk assembly. Sure, it was a good idea in the sense that mapping is a *little* bit faster since it’s binary and running on CLR blah blah blah…at the expense of flexibility: You need to re-compile and re-deploy your freaking BizTalk application if you want to make a change in your map.

I use external XSLTs on my BizTalk map, and it’s a good thing BizTalk allowed us to do so instead of using that atrocious BizTalk mapping tool. Even with that option, BizTalk *still* compiles the external XSLT into the map!

A lot of attempts have been made to bring back this concept of “dynamic maps” but each attempt I saw was lame and/or introduces complexities that I’d rather not deal with: This usually involves the use of custom pipelines that inflexible or using Orchestrations that incurs an unnecessary overhead.

We have a BizTalk Map. Wouldn’t it be great if we can contain our customizations there? This way, We can use it in an orchestration, Receive location, AND send ports just like a “regular” BizTalk map. Well, my friends, you’re in luck. I believe I have found the holy grail of Dynamic biztalk Transforms in BT2006!

Basically, this “special map” will obviously not contain the reference to your external XSLT; it will only contain a n XSLT that references a custom assembly that dynamically loads your actual external XSLT! What this means that even if you change your XSLT, you don’t need to recompile your BizTalk assembly! How cool is that?!

This first link is the XSLT that calls the dynamic XSLT loader, along with the external object XML which defines the location of the dynamic XSLT loader assembly. You create your BizTalk map as usual, then at the properties reference “Custom Extension XML” and “Custom XSL Path” respectively.

The third link is an implementation of the XSLT loader. This loader is pretty basic, but I isolated the interface that does the actual loading called IDynamicMapLoader. You just need to create a regular .NET Assembly, sign it and load in the GAC. I’m not going to expound on what the C# library does since this ain’t .NET Programming 101 Blog. Although I just need to point out the XML that it loads to reference the actual XSLT: maplookups.xml. Here is where you define your XSLT key and the corresponding URI location of the YOUR XSL that will “dynamically” change at runtime.

if you look at DynamicMap.xsl:

<xsl:variable name=”dynamic-map-result” xmlns:DynamicMap=”http://ap.org/BizTalk/DynamicMap” select=”DynamicMap:Transform(’default’, $xml-doc)” />

the ‘default’ is the same key that is in:

<Map Name=”default” Uri=”c:\eai\components\default.xsl” />

That means that in this DynamicMap call, it loads “c:\eai\components\default.xsl” AT RUNTIME. I can change my default.xsl anytime without having the need to recompile the BizTalk assembly!

Of course, the downside is it reads the XSL everytime the map is executed, and this is where your creativity comes in: You just need to write your own implementation of IDynamicMapLoader to make it faster and/or more efficient without sacrificing the main feature: DYNAMIC TRANSFORMS!

I actually wrote a better implementation of IDynamicMapLoader but that’s beyond the scope of what I want to share here (here’s a hint: I used Enterprise Library Caching Block)…

I just showed you the door, it’s up to you to walk through it. :-)

Dynamic Map XSLT
External Extension XML
Dynamic Loader class
MapLookups XML

Oh, make sure that the External Extension XML has the correct PublicKeyToken (i.e., has the public key of the digital signature you sign the Dynamic Loader class assembly with)

GoodLink = Jerks

April 3rd, 2008

I just got a new phone with Windows Mobile 6.  Ironically, in order to connect to my day job’s Exchange server to get my mail via IMAP, I cannot use the built in Mail client; I need to install a third-party application called GoodLink.

That’s fine, except this software “hijacks” (replaces) the default Contacts application on the home page.  Worse is that there is no setting on GoodLink nor Windows to turn off this stupid feature.  It would have been OK if GoodLink contacts is better.  It is not.  Interface is abysmal.  When I pair my phone with a Bluetooth device, guess which contacts list it tries to load?  Caller ID?  Sync with Windows/Mac.  Yes, it’s the default one, not the GoodLink contacts. 

GoodLink = FAIL.  You guys suck.

How to Spread Tumor on the Intarwebs Without Really Trying

March 25th, 2008

I started doing research about the Amazon Kindle and while googling reviews, I came across this odd review from who considers himself a “professional blogger” and “a former Microsoft Technology evangelist” (WTF kind of a profession is that?). 

The guy is totally obnoxious in his review, and pointed out complaints about the Kindle that’s waaaay off base.  I was so pissed with his review that I left a comment on his blog entry (I left my full name as the commenter).  Imagine that.  I don’t even own a Kindle yet and I felt compelled to defend the product!

How this guy garnered so much following is just beyond me, really.  I read some of his other blog entries and could not help rolling my eyes.  And…Oh my Gawd…he has a Wikipedia entry?  What’s the world coming to???

No, I’m not giving a direct link to that review.  You’ll know what I’m talking about when you get there.

LINQ: A Programmer’s Confession

March 25th, 2008

I have a confession to make: I don’t get LINQ.  I don’t get it at all.  “I don’t get it” not in the sense that “I don’t understand it.”  Oh, I understand it…but I don’t really “get” what it’s for.

Read the rest of this entry »

PowerShell Annoyances

August 24th, 2007

We usually use a combination of WSH and good ol’ batch files to create our BizTalk applications deployment scripts…to make it easy enough that even a monkey can do it.

Since the advent of PowerShell, I’ve always wanted to infuse that technology to make our installers even better. Just yesterday, I re-wrote the main installer batch file to PowerShell and it has been a tough transition, to be quite honest; you need to re-think a lot of ways of how you do things with WSH + batch files:

For example, in batch files or WSH, you expect that when you call an external app (without using “start”), you expect the script to “block” until the external function exits. Not so in PowerShell. It goes to the next statement immediately as you launch the external app. At first I was annoyed by this at first, but after reading this, it sort of makes perfect sense.

Now the next one really stumped me for a while. I call the BTSTask function to do a lot of things in our deployment scripts. at first, this statement in my script fails:

invoke-expression (’BTSTask ImportBindings -Source:{0} -ApplicationName:”{1}”‘ -f $BindingsFile,$BizTalkHostProperties.name) | out-host

For some reason, when you execute that statement, BTSTask would bitch that I did not pass any arguments. WTF?

While trying to understand this, it occured to me that MAYBE Powershell is treating -Source and -Application name as PowerShell arguments instead of arguments to BTSTask…so what if i ESCAPE the hyphen? Guess what? it worked.

invoke-expression (’BTSTask ImportBindings `-Source:{0} `-ApplicationName:”{1}”‘ -f $BindingsFile,$BizTalkHostProperties.name) | out-host

Again, it sort of makes sense, but for someone starting out with PowerShell, this is very annoying.

With all that complaints said, I’m not going back to WSH+batch files. PowerShell is awesome. I just wish it’s part Visual Studio 2005.

SQL Adapter and MS DTC Issues

July 24th, 2007

If you are using the SQL Adapter in a BizTalk solution that connects to a separate database server other than the MessageBox/BTConfig database, you might encounter errors with this message:

“An error occurred while enlisting in a distributed transaction.”

I know, it’s impossible to get any more cryptic than that. 

Well, unfortunately for me, I did.  And even after following this procedure STEP BY STEP http://msdn2.microsoft.com/EN-US/library/aa561924.aspx, I am still getting that error.

The clue that led me to believe that the DTC between the BizTalk servers and the DB server is still not working was the fact that DTCPing was giving me this warning:

“WARNING:the CID values for both test machines are the same”

It turns out, though, that this is caused by some OTHER problem…mainly something to do with CIDs.  Thanks to Google,  I found this thread

http://www.webservertalk.com/archive167-2004-11-427303.html

Which pointed to KB 306843.

http://support.microsoft.com/kb/306843

Only after doing step 11 of that KB fixed the whole issue on BizTalk and DTC problems.

Using COM with BizTalk 2006

June 12th, 2007

Back in the good ol’ days of BizTalk 2002 where everything fine and dandy with COM and C++, I wrote a number of BizTalk “parsers.”  “Parsers” translate to “pipeline components” in the BizTalk 2006 universe, and in one project I’m involved with is to migrate this one parser to BizTalk 2006. 

I’ve seen the whitepaper on BizTalk and its recommendation is to re-write the whole thing in C#…Um…riiiight.   I was not willing to re-write that monstrosity in C# although it’s a relatively not-so-complicated task.  So what I did was to isolate the code that does the parsing and created a COM component using ATL Wizard in C++ Visual Studio 2005.

The COM component is called in a custom pipeline component, which is OK until we actually deployed it for unit testing.  I forgot that everything must be strong named in BizTalk 2006 but the generated Interop DLL when you add the COM reference in the custom pipeline component.  In this case, the option is to copy the Interop DLL in the %PROGRAMFILES%\Microsoft BizTalk 2006 folder, which is kludgy…

Then I read this thread about strong-naming the Interop DLL.  Basically, you use the tlbimp.exe tool to generate the Interop DLL, and you can specify your strong name key using the the tool.  NIIICE….

SQL Service Broker n00b Blues

May 9th, 2007

There’s a million pages telling you about how to create message types, contracts, queues, services….and sending and receving from service broker queues.  The thing that’s annoying about all these tutorials is that they fail to mention that you need to “enable service broker” on the database you’re working on before you can actually do service broker…um, stuff.

I would not bore you with details on how I found that out (hint: it involves ingestion of lethal dosage of Ritalin), suffice to say there are two ways:

1.  select * from sys.transmission_queue - This allows you to check the “pending messages” on the queue.  if there’s entry in there, chances are, your queues ain’t runnin’

2.  select is_broker_enabled from sys.databases where name = [dbname] - I don’t need to explain this.

if is_broker_enabled is 0, you need to enable service broker on your database, which can be done by:

use master
alter database [dbname] set ENABLE_BROKER with no_wait

IMPORTANT: This requires an exclusive lock to the database, so make sure that SQL Service Agent is shut off and kick out any current users of the database.  The with no_wait option is to prevent unnecessary wait if the resource can’t be locked…