In AX you can comsume third party components in various ways – it could be a dynamic link library (dll) a webservice or maybe a quite different ressource. But whatever ressource you are using, they all have one thing in common – it can be quite challenging when using them fails and You need to trouobleshoot, because AX is not particularly good in providing usefull error messages. In this post I will try to sum up some of my findings and maybe provide You with some tips on how to troubleshoot. Please feel free to contribute as I am sure my list of things isn’t nearly covering all scenarios.
The overall most common error is: “CLRObject could not be created” – no hints at all of what the problem might be… Here are some things you should consider…
When using dll’s or visual studio projects wihtin AX 2012 please consider Your CPU architecture. I quite often run into problems where everything works just fine when run on the client, but when running on the server it fails. This may be caused by the fact that the assembly is compiled for a specific architecture eg. x86. The ax client runs in 32 bit mode wheras the AOS server mostly runs in 64bit mode. And ofcourse this mismatch has to fail. Here’s what You should do:
- If You are in control of the dll/assembly make sure it is compiled for any cpu.
If using visual studio projects inside the AOT disregard the warning stating something about using different CPU architecture.
- Make sure the dll doesn’t wrap other ressources. On one occasion I had a dll that was compiled for any cpu, but it wrapped a 32 bit COM object.
- If you are not in control of the dll/assembly you can try and remove the corflag header (information about the bitness) using CorFlags – https://msdn.microsoft.com/en-us/library/ms164699%28VS.80%29.aspx?f=255&MSPPError=-2147217396.
Another great post about Corflags can be found here – http://www.codeproject.com/Articles/383138/BadImageFormatException-x-i-x
- If that doesn’t work and You are forced to use af 32 bit assembly on a 64 bit AOS, a good way to solve this would be to host the 32 bit dll/assembly in a webservice. This solution would provide a clean interface across the 32bit and 64 bit architecture.
If You are in for a more hardcore solution maybe this would be of interest – http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/
- Make sure the dll/assembly is located in both client/bin on the client and server/bin on the AOS server. If using visual studio pojects wihtin ax, the deploy folder for the server is most likely server/bin/VSAssemblies. if using multiple AOS’es make sure the dll/assembly is deployed to all AOS servers. Remember to restart the AOS after deploy in order for the AOS to load it/them.
- Make yourself aware of where the code is running – server or client? You need to know where the problem originates from.
- If the dll originates from the “internet” make sure it’s not marked as “blocked” when viewing the file properties. Windows sometimes marks downloaded items as blocked.
- Another thing worth mentioning is having a proper error handling routine in your code. It might just provide You with some more clues about whats going wrong. Here’s what I usually do:
public void send2DLL()
PRDeviceWrapper.XMLDevice wrapper; //the assembly
interopPermission = new InteropPermission(InteropKind::CLRInterop);
wrapper = new PRDeviceWrapper.XMLDevice(); //<– this is where most errors occur
request = this.createRequest();
returnValue = wrapper.RequestXML(request, byref answer);
e = clrinterop::getLastException();
e = e.get_InnerException();
e = clrinterop::getLastException();
- Another approach could be the one suggested by Goshoom. His routine can aslo be used when testing whether a certain type located in a certain assembly can be found or not. His entire post can be found here – http://dev.goshoom.net/en/2011/10/assembly-containing-a-given-type/
public static void showContainingAssembly(str _typeName)
System.AppDomain appDomain = System.AppDomain::get_CurrentDomain();
System.Reflection.Assembly assemblies = appDomain.GetAssemblies();
int numOfAssemblies = assemblies.get_Count();
for (i = 0; i < numOfAssemblies; i++)
assembly = assemblies.get_Item(i);
if (assembly.GetType(_typeName, false, true) != null)
info(strFmt("Assembly full name: %1", clr2XppStr(assembly.get_FullName())));
info(strFmt("Assembly location: %1", clr2XppStr(assembly.get_Location())));