Component Links not working in 64 bit mode - tridion

Brief Summary:
We are using Tridion 2009 SP1, however we never used .NET templating, we are still using R5 concept i.e. (VBScript, XSLT etc), we are using broker database for our linking etc.
Our Tridion Server/Presentation Server/services are running perfectly on 32 bit environment/mode, our IIS is running on 32 bit mode. Everything is running perfectly.
Problem:
We recently decided to move all our server to 64 bit mode, so now everything moved to 64 bit (IIS, Tridion Server/Services etc), everything is working perfectly except the Component Links. Due to that we again moved our Tridion services to 32 bit mode as well as IIS to 32 bit mode and then component links start working
Error:
When all the things are running on 64 bit mode, we are getting component link resolving error and getting below error when it trying to resolve the component.
Error Failed to resolve component uri tcm:233-218990 while called from ComponentLink.ResolveLink on /english/index.aspx
... EGIT.CCIT.Tridion
... Object reference not set to an instance of an object.
... at EGIT.CCIT.Tridion.COM.ComponentLink.GetLink(String pageURI, String componentURI, String componentTemplateURI, String attributes, String text, Boolean textOnFail, Boolean anchor)
... at EGIT.CCIT.Tridion.Broker.LinkResolver.ComponentUrl(String pageUri, String uri, String componentTemplateUri, String publicationUri)
...
09:50:58.90 Error Error in Core Tridion call
... netrtsn
... Attempt to load JVM failed on native side
... at Codemesh.JuggerNET.JvmLoader.Load(Boolean bAcceptPreloaded)
... at Codemesh.JuggerNET.JvmLoader.Load()
... at Codemesh.JuggerNET.JavaClass.init()
... at Codemesh.JuggerNET.JavaClass.get_JObject()
... at Codemesh.JuggerNET.JavaMethod.init()
... at Codemesh.JuggerNET.JavaMethod.get_MethodPtr()
... at Codemesh.JuggerNET.JavaMethod.get_Handle()
... at Codemesh.JuggerNET.JavaMethod.CallObject(JavaProxy jpo, JavaMethodArguments args)
... at Com.Tridion.Linking.ComponentLink..ctor(Int32 publicationId)
... at Tridion.ContentDelivery.Web.Linking.ComponentLink..ctor(Int32 publicationId)
... at EGIT.CCIT.Tridion.COM.ComponentLink.GetLink(String pageURI, String componentURI, String componentTemplateURI, String attributes, String text, Boolean textOnFail, Boolean anchor)
Please suggest!!
Thanks.
Best Regards,
Manu

Manu,
You can use VBScript templates (thought it is a good idea to start moving off this platform anyway) in your CMS backend and 64-bit on the front end, if your front end is .NET or Java.
What you cannot do is use COM on the Front-end (even if being called from .NET) and be on 64 bit, since the Tridion COM-based linking API is 32 bit only.
The .NET linking libraries and the Java linking libraries are 32 and 64 bit compatible, but not the COM libraries.
Hope this helps
N

Which version Java did you install on the presentation server? Is it 64-bit? Try the 32-bit version of Java. Otherwise try the 64-bit version.

Related

Groovy has a size property for Collection?

I have written a piece of code where I'm checking the size of an ArrayList like:
[1,2,3].size
All works well on Groovy Console and with Grails embedded Tomcat server. But once I deployed this code to Websphere Application Server, I receivec an exception stating
Exception evaluating property 'size' for java.util.ArrayList, Reason: groovy.lang.MissingPropertyException: No such property: size for class: java.lang.Integer.
After a while of debugging, testing and plenty of WTFs, I realized that there were parenthesis missing from the method call. The property notation should not work as there's no method getSize() for Collection (it's plain size()) and this all makes sense.
What's puzzling me, is why does someCollection.size work on Groovy Console and Grails?
Grails and Groovy Console version is 2.3.6
ArrayList in (at least) the Sun JDK 1.7u67 and in OpenJDK 1.6 holds a private int size, which is accessible to groovy. If your other environment uses another JDK, this var might not exist and groovy would fallback to the interpretation of [1,2,3]*.getSize(), which then fails.

msvcr71.dll crashing IIS 7 app pool on Windows Server 2008 w/ ASP.NET 4

I am working on a project that requires a C library that I have wrapped with managed code. The C library is compiled for 32-bit and I've figured out that it requires msvcr71.dll. Problem is that this DLL does not come stock with Windows Server 2008 in the SysWOW64 directory for whatever reason.
I've copied the DLL from SQL Management Studio on the system, and I can verify that it works in a standalone EXE on the server. There is nothing preventing it from working.
HOWEVER... when I link it into my ASP.NET application and ensure both my library's DLL and msvcr71.dll are in my /bin directory the application pool for my site falls out from under me. werfault.exe fires up, eats a bunch of CPU and RAM, then goes away and leaves me this mostly useless log in the Event Viewer.
Then the application pool restarts and waits to fail again. It's running with .NET 4 in Integrated mode. The site is based on MVC 3.
Faulting application name: w3wp.exe, version: 7.5.7601.17514, time stamp: 0x4ce7a5f8
Faulting module name: ntdll.dll, version: 6.1.7601.17725, time stamp: 0x4ec49b8f
Exception code: 0xc0000374
Fault offset: 0x000ce6c3
Faulting process id: 0x998
Faulting application start time: 0x01cd753eb1fcd760
Faulting application path: C:\Windows\SysWOW64\inetsrv\w3wp.exe
Faulting module path: C:\Windows\SysWOW64\ntdll.dll
Report Id: 7b54f020-e132-11e1-a34d-404094d3cf82
What on earth is going on here? I'd love to have the DLL linked right into my ASP.NET site but I am on the brink of just writing a proxy application... I'd like to avoid that hack if possible. Thanks.
Side note All of this works perfectly fine on my local machine. It's only on the server that I'm having real trouble getting it linked into IIS.
UPDATE
This appears to be an interop problem when running inside of IIS, particularly with string methods... I am looking into it now...
http://blogs.msdn.com/b/asiatech/archive/2009/12/24/net-application-may-crash-on-windows-2008-when-calling-function-from-native-c-dll.aspx
Hate to answer my own question, but it needs a solution recorded for everyone else. The core problem I had here was not actually msvcr71.dll (thought in the end I did end up recompiling the original C source for the library in question against version 10 of the C runtime msvcr100.dll since it is included in Windows Server 2008 by default.
I am still running the library against x86. However the real problem here is that there is some kind of memory management bug (or feature, you decide) that causes IIS 7 to crash when doing Interop on P/Invokes with strings in .NET. I think it was intended as a security feature... who knows.
Check out the article listed in the question update above for partial details on this:
http://blogs.msdn.com/b/asiatech/archive/2009/12/24/net-application-may-crash-on-windows-2008-when-calling-function-from-native-c-dll.aspx
The specific library I am working with is for Shapefiles from GIS tools if you are that curious.
http://shapelib.maptools.org/
This made some sense to me, but my library is written in C and not C++. Regardless, neither language is my strong suit and I could not find a CoTaskMemFree method that existed in the C compiler. It's probably my own fault, but I really didn't have time to learn and rewrite some ancient C code.
I figured out that I could just not marshal a string back using .NET methods and instead do it manually from IntPtr to prevent IIS from crashing.
Here's my original import:
[DllImport("shapelib.dll", CharSet = CharSet.Ansi)]
public static extern string DBFReadStringAttribute (IntPtr hDBF, int iShape, int iField);
...and here's what I had to change it to:
[DllImport("shapelib.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr DBFReadStringAttribute (IntPtr hDBF, int iShape, int iField);
That change by itself stopped the application from crashing. Then I had to create this sort of hack to pull the strings out. I know this has to be far from optimist but it's the best I could do for now.
Here's what I ended up doing in the end...
public static string DBFReadStringAttribute(IntPtr hDBF, int iShape, int iField)
{
IntPtr dataPtr = _DBFReadStringAttribute(hDBF, iShape, iField);
string output = Marshal.PtrToStringAnsi(dataPtr, 255); //255 is the supposed max length for DBF databases
int idx = output.IndexOf('\0');
string strData;
if (idx > 0)
strData = output.Substring(0, idx).Trim();
else
strData = "";
return strData;
}
[DllImport("shapelib.dll", CharSet = CharSet.Ansi, EntryPoint = "DBFReadStringAttribute")]
private static extern IntPtr _DBFReadStringAttribute (IntPtr hDBF, int iShape, int iField);
Additional note
For whatever reason Marshal.PtrToStringAnsi(dataPtr) did not retrieve the string properly (it would come out corrupted). I had to set a maxlength and parse it myself.

Qt - write to registry 32/64 issue

I'm writing a Qt application for windows, and using windows 7 64 bit.
The application has to write to the registry, I tried to use QSettings class, but as I found in the documentation:
On Windows, for 32-bit programs running in WOW64 mode, settings are
stored in the following registry path:
HKEY_LOCAL_MACHINE\Software\WOW6432node\MySW
Is there a way to override it and write to: HKEY_LOCAL_MACHINE\Software\MySW directly?
Clarification:
The application is writing to the registry, the keys written are to be used by other application, which I cannot know if running on 64 or 32 bit mode.
I know it is possible in C#, so it must be possible in C++.
See this article on MSDN:
32-bit and 64-bit Application Data in the Registry
It appears that using some of the Win32 API you might be able to change how this behaves. Although I'm not sure why the default behavior won't work for you.
I suppose that if you want to do it in Qt then this would be the most appropriate way:
[ Source: http://doc.qt.digia.com/4.7/qsettings.html#accessing-the-windows-registry-directly ]
Accessing the Windows Registry Directly On Windows, QSettings lets you access settings that have been written with QSettings (or settings in a supported format, e.g., string data) in the system registry. This is done by constructing a QSettings object with a path in the registry and QSettings::NativeFormat.For example:
QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Office", QSettings::NativeFormat);
All the registry entries that appear under the specified path can be read or written through the QSettings object as usual (using forward slashes instead of backslashes).For example:
settings.setValue("11.0/Outlook/Security/DontTrustInstalledFiles", 0);

'ToArray' is not a member of 'String'

I found a code example online that purports to count the number of pages in a PDF file. However, I'm getting the error 'ToArray is not a member of 'String' on the following line:
Dim pdfMagicNumber() As Char = "0000".ToArray
I'm running VS 2010 on a Framework 2.0 project, on a machine running Windows 7 and IIS 7. I found one article that talked about IIS configuration as the culprit for this error, but my settings seem to be consistent with what they recommended.
Any ideas on this error?
Thanks!
Mike
ToArray is an extension method introduced in .NET 3.5 on IEnumerable<T>. It works in .NET 3.5+ when called on string, as string implements IEnumerable<char>.
However, string.ToCharArray() is available in all versions of .NET, and even when you're using .NET 3.5+, it will be more efficient than ToArray.
In other words, you want:
Dim pdfMagicNumber() As Char = "0000".ToCharArray

Classic asp - 64 bit MDAC reference problem

I got an very basic test.asp page that needs to run on a 64-bit server
first i tried
<!--METADATA TYPE="TypeLib" NAME="Microsoft ActiveX Data Objects 2.5 Library" UUID="{00000205-0000-0010-8000-00AA006D2EA4}" VERSION="2.5"-->
<%
.... more code
does not work (even though i found the reference in COM)
the i try
<!--METADATA TYPE="TypeLib" NAME="Microsoft ActiveX Data Objects 2.8 Library" UUID="{2A75196C-D9EB-4129-B803-931327F72D5C}" VERSION="2.8"-->
<%
... more code
this works ,, but why can't i reference the 2.5 version when the library exist on the server?
Josip is nearly correct MDAC 2.5 is only 32 bit (2.8 has a 64 bit flavour). By default on 64 bit server your application pool will run using 64 bit processes. It will be looking in the 64 bit version of the system hive for the 2.5 type library reference but won't find it (its only in the 32 bit version).
If you edit your application pool settings so that it runs as 32 bit you should find the 2.5 reference will work.
MDAC is available only on 32-bit.
You must change your application to target x86 (by default it targets AnyCPU). It will still run on x64 but with smaller memory space.

Resources