I noticed an interesting thing about .NET Generic classes while fixing a bug (Thanks Shigeru Nakagaki for logging it). He was not able to use .NET class ‘System.Collections.Generic.List’ . Here is the code he was trying.
<cfset list = CreateObject(".net","System.Collections.Generic.List")>The proxy generator itself was throwing an error saying that this class was not found which was quite mysterious because this class is part of core .NET library. With little debugging I found the reasons which is quite fascinating.
A Generic class will have some types associated. For example, System.Collections.Generic.List<T> has one associated type ‘T’ where T will be any type like String, int or whatever. For Generic classes, the class name that .NET actually stores is different than the specified one. It actually stores the class name as <className>`<No of Types>. Notice the backquotes ‘`’? So for ‘System.Collections.Generic.List’, the actual .NET class name is “System.Collections.Generic.List`1″. Similarly for ‘System.Collections.Generic.Dictionary<T, T>’ the actual class name is ‘System.Collections.Generic.Dictionary`2′ . This is quite different from Java Generics where the type information is not written to bytecode and hence the class name never changes.
After figuring this out, I changed the code name like this (reluctantly as this is not a valid class name)
<cfset list = CreateObject(".net","System.Collections.Generic.List")>and this time, the error was something different. The proxy got generated fine but it still complained that it could not find the class which I had expected because backquotes ‘`’ is not allowed in a java class name. (In case you are not aware, for using .NET classes in ColdFusion, we generate a java proxy for a .NET class and the invocation happens through that proxy – See my MAX 06 presentation ). The immediate question them comes is – what was the name of the proxy class that got generated? And the proxy class was generated with name “System.Collections.Generic.List__1″. Notice that backquote ‘`’ was replaced with two underscores ‘__’.
So we wanted to use ‘System.Collections.Generic.List’, but its actual .NET class name was “System.Collections.Generic.List`1″ and its java proxy name was “System.Collections.Generic.List__1″. Interesting. Isn’t it?
Now the question is – how do you use it? If you give the class name as ‘System.Collections.Generic.List`1′, the class loading will fail and if you give the class name as ‘System.Collections.Generic.List__1′ the proxy generation will not happen. The workaround for the time being is
- Generate the proxy for required classes separately using proxy generator (jnbproxyGui.exe)
- Use the proxy jar in assembly list of createObject
- Use the generated java class name with ‘`’ replaced by ‘__’.
Here is a sample code that uses .NET List<String>.
<cfset eventList = CreateObject(".net","System.Collections.Generic.List__1", "dotnetProxy.jar")> <cfset dotnetstring = createObject(".net", "System.String", "dotnetProxy.jar")> <!--- create a List of type String ---> <cfset stringType = dotnetstring.getDotNetClass()> <cfset eventList.init(stringType)> <!--- Add Events to List ---> <cfset eventList.add("MAX")> <cfset eventList.add("CFUNITED")> <cfoutput>#eventList.Get_Count()#</cfoutput>
For CF9, you will not need this workaround as we will do the .net class name to java class name translation automatically.

#1 by inj on August 13th, 2009
| Quote
Hi, Rupesh!
I just try to use your last code and get an error:
“The C:\ColdFusion9\wwwroot\WEB-INF\cfclasses\dotNetProxy\dotnetProxy.jar file specified in the assembly does not exist”
What’s wrong?
#2 by Rupesh Kumar on August 14th, 2009
| Quote
The fix done in CF9 is not available in the public beta. So you have to follow the steps I mentioned above. You will have to generate the proxy jar using JNBProxyGUI. I had generated the proxy jar with name “dotnetProxy.jar” and placed it in the cfclasses\dotnetProxy directory. You can generate with any path and provide that path in the createObject.
#3 by Paul on November 20th, 2009
| Quote
Did this get fixed for CF9 because either I’m still seeing the “Class System.Collections.Generic.List not found in the specified assembly list. ” error.
#4 by Rupesh Kumar on November 23rd, 2009
| Quote
Yes. it did get fixed in CF9. Could you confirm that it does not work for you?
#5 by Paul on November 23rd, 2009
| Quote
Hi Rupesh. Yes when I tried this code:
I got the same error mentioned.
However this code:
Worked as expected.
#6 by Paul on November 23rd, 2009
| Quote
Wont work:
cfset list = CreateObject(”.net”,”System.Collections.Generic.List”)
Works:
cfset eventList = CreateObject(”.net”,”System.Collections.Generic.List__1″, “dotnetCoreProxy.jar”)
WordPress removed the code in the first reply.
#7 by Andrew Scott on November 21st, 2009
| Quote
Rupesh you mght want to update this blog to change dotnetProxy.jar to the correct name dotnetCoreProxy.jar
#8 by Rupesh Kumar on November 23rd, 2009
| Quote
Andrew,
See my reply above. It was the name of the proxy jar that I generated. It is not the same jar as dotnetCodeProxy.jar.
Rupesh
#9 by Andrew Scott on November 23rd, 2009
| Quote
Rupesh, All I know is that the code you posted does not work. However if you change the code as I listed above, it will run without any problems.
#10 by Rob on November 23rd, 2009
| Quote
Rupesh,
I am still receiving the Class not found in the specified Assembly using the CF9 Developers Edition. I am using the following code (as per your example)
and generating that error. How should I proceed?
Thanks,
Rob
#11 by Brent Lamborn on February 5th, 2010
| Quote
There seems to be a similar issue with .NET nullable types such as DateTime?. Nullable DateTime throws a similar exception.
#12 by Tom on March 5th, 2010
| Quote
Just thought I’d post this note here. We were struggling to get the JNBridge to work and it was like JNBProxy.exe wouldn’t create the jar files on the fly but if I manually create with JNBProxyGUI.exe then it works. Seemed like a file permission problem but we finally realized it was our Sandbox Security in CF8. So the lesson is: The path to /jnbridge must be in the security sandbox of the app or the whole thing is going nowhere.