I am working with a java program where I need to call a native library in order to call other dll that in turn would contact some Remote "Amadeus" (Airline related service) service.
Problem statement:
The jni dll creates a session every time it contacts the remote service and close the session after completion of its intended task. Its very similar to jdbc approach where no connection pooling is involved.
Now it seems that the session is actually not being closed properly and at the server end it eventually results in max session exception and refusing any further connection requests.
It seems there is some issue at the dll-remote service connectivity end, because from java code the connection is being properly closed by calling the native call.
Workaround identified:
Restarting the application fixes this issue because it forces all open connection getting closed.
We don't have access to alter the dll for the time being, so we are thinking if we could have the same flavour of restarting the jvm without actually restarting the jvm but reconnecting (unloading and reloading) the dll.
Here we think if we can disconnect the dll, all memory allocated to the dll would be cleared off, and hence would force to close/collect the open sessions at server end.
Question:
Can we really unload and then reload the dll without restarting the jvm?
Please help us.
Thanks in advance.
Krgds,
Debojit
You can unload it. It's probably not safe to do so, however.
Assuming you're running on a Windows platform, without knowing the details of the DLL, it's not possible to safely unload the library. Per the documentation for the FreeLibrary function:
Use caution when calling FreeLibrary with a handle returned by
GetModuleHandle. The GetModuleHandle function does not increment a
module's reference count, so passing this handle to FreeLibrary can
cause a module to be unloaded prematurely.
Since you're not going to have direct access to the handle used to load the library nor all the references into the library, you can't know if all references to the library are no longer used.
Also, unloading the library may not solve your problem. Ending the entire process solves the problem because that causes everything that process uses to be released/closed (for the most part - there are always exceptions...). Simply unloading one library loaded into the address space doesn't do that. Unloading the library might do what you want - if the library is designed to work that way. Given that it's apparently not working properly when used normally, I'd say the odds of it working properly when used abnormally aren't very good - if unloading the library while it's being used doesn't cause even worse problems.
You need to actually solve the problem - not simply try things and see if they work.
Related
I have a Windows forms application which I have a bit of a sporadic issue with. The application would randomly start/spawn another instance of itself without any warning or reason. I only have one use of Process.Start in the whole application (15 forms/files and about 5000 lines of code) and that calls a net use command to map a network drive.
I've not been able to reproduce this in my testing and therefore I made the project a Windows Assembly Framework single instance application (pros/cons of this I know). This has obviously stopped any other instances of the application from running, but now at random intervals their program will minimise and snap to another application they have running. I don't know for certain whether this is related but they certainly sound a bit close for comfort!
Any ideas/pointers/thoughts appreciated.
Thanks,
Jamie
This could happen if the application, at some point, calls Application.Restart.
Background
We have a .NET WinForms application written in C# that interfaces to a handheld store scanner via a console application. The console application is written in good ol' VB6-- no managed code there. The VB6 application consists of several COM objects.
The .NET WinForms application refreshes the data in the scanner by invoking the console application with the right parameters. When the console application starts, it pops up a modal form reminding the user to place the handheld device into its cradle.
Problem
A customer has a bizarre situation in which the call to start the console application appears to hang before it displays the reminder form. If the user presses any key-- even something innocent like Shift or Alt-- the application unfreezes, and the reminder form appears. While it is hung, the CPU usage of the console application is very high.
We have obtained a memory dump from the command line application using ProcDump. I have some experience debugging managed dump files, but this VB 6 dump is strange to me.
We captured several full memory dumps in a row. In some of them, there appears to be COM glue stacks. For example, several dump files show a call stack like this:
msvbm60!BASIC_DISPINTERFACE_GetTICount
msvbm60!_vbaStrToAnsi
msvbm60!IIDIVbaHost
msvbm60!rtcDoEvents
msvbm60!IIDIVbaHost
msvbm60!BASICCLASS_QueryInterface
[our code which I think is trying to create and invoke a COM object]
It doesn't help that the only symbols I have are from our code. The Microsoft symbol server does not have a PDB file for msvbm60.dll (or at least not from their version which is 6.0.98.2).
Questions
I am suspecting there may be some COM threading issue that is happening only on their system.
1) How can I determine the thread state of each thread in a dump file? If this were a managed dump file, I would look at !threads and then !threadstate to figure out the thread states. There is no managed code, so I can't use sos.dll. I didn't see any hints using ~ and !teb.
2) Is there a way to see what COM objects have been created in a dump file? Again, in a managed dump, I can do a !dumpheap to get a list of managed objects. Is there something similar I can find for COM objects?
3) Can I determine the threading model of COM objects in the dump file?
You can dump thread state by using command:
~*
this will not display 'background' as a state, you will only see running, frozen or suspended.
I'm not sure how you can get information from COM objects, I have never tried but will investigate and get back to you, regards to threading model it will be difficult to infer that without painful monitoring of application state after stepping through and even with that, when you step through all other threads will run unless you use .bpsync 1 which syncs all threads to the current one, but that could cause a hang (e.g. gui thread has now been told to freeze) so I think it will be difficult unless you have access to the source code.
I can only answer question 1. Use !runaway to find the thread or threads consuming the CPU. To get all thread stacks use ~*kb1000.
We have upgraded our development SAP system from ECC6 SPS3 to ECC6 SPS5.
An application external to SAP (KOFAX - a SAP certified product) passes an invoice image and invoice data to the SAP system. It then calls the Function Module Z_DICOM_STORE_USING_FB60_FB65 (supplied by KOFAX) in order to store the image on the SAP Content Server and trigger a workflow.
Before the upgrade of the SAP system, this worked, now it does not. An exception is raised within form check_and_add_delimiter (subroutine pool SCMS) which is effectively called from function module SCMS_ARCHIVE_INFO_GET.
The exception is raised because when class method CL_GUI_OBJECT->CLASS_INIT is called, the flags:
GUI_IS_RUNNING
ACTIVEX
JAVABEAN
WWW_ACTIVE
are set to blank values.
This happens when the process is kicked off from the KOFAX GUI. If I run Z_DICOM_STORE_USING_FB60_FB65 from transaction SE37 and populate the structures with the same data, the image is stored and the workflow is triggered.
Please can you suggest why the flags are not being populated when the program runs?
Thanks.
This is a "technical duplicate" of you other posting. Again, the issue is clear - the "KOFAX GUI" appears to use a RFC connection to call the function module, but the function module then uses some other stuff that requires not a RFC connection, but a full-blown SAP GUI at the other end because it tries to access SAP GUI attributes. I'm not into CMS, so I can't help you to figure out why this was changed during the upgrade...
For most scenarios a normal RFC connection is sufficient, SAP GUI is only required if you try to execute BDC within the function module (e.g. for "direct posting"). Since you say that it worked before I can only assume that this is not the case.
Could it not be that the error happens during the upload of the image? Maybe the upgrade did something to the content server configuration? There is a test program for the content server that you can run.
This was resolved by one of our develpers. The answer he gave me was:
We modified check_and_add_delimiter
(subroutine pool SCMS) in order to
overcome this problem (we effectively
stopped the bit of offending code from
being called)
I'm writing managed code that has to interact with a vendor's COM automation server that runs out of process. I have found that this server becomes unstable if more than one client connects to it. For example, if I have managed code in process A and managed code in process B both connecting to this COM server, a single process will be spun up for the COM server and it's behavior is less than reliable. I'm hoping there's a way to force a separate process for each client - server connection. Ideally, I'd like to end up with:
Managed Process A talking to COM Server in process C1
Managed Process B talking to COM Server in process C2
One thought that came to mind was that if I ran process A and process B with different security identities, that that might cause the COM infrastructure to create separate server processes. I'd rather not go down that road, however. Managed Process A and Managed Process B are actually Windows Services. And I'm running them with identity Local System (because I need them to be able to interact with the desktop, and you can't check the "Interact with Desktop" box on the services applet for services that don't run as Local System). And the reason I need to interact with desktop is that this COM server occasionally throws up a dialog box on the screen and if the service itself cannot interact with the desktop then the COM server is spawns can't display the dialog (I believe it is displayed on a hidden WinStation).
Place the component registered at COM+, this put an isolation layer at your.
Use : Control Panel->Administrative Tools
or cmd/execute DCOMCNFG
Component Services->Computers->My Computer->COM+ Application, right click, new application, next, Create an empty application, enter app name “COM+ your.dll”, next, select Local Service, next, next, next, finish.
In new item made, expand, at Components, right click, new component, next, select Install new component, select your component.
Click Component properties, tab Identity, select System Account.
For errors in calls see Event after.
It's been a while since I've done this, so my memory is hazy.
If you configure the OOP COM server as a DCOM server using the DCOM config tool, I believe you can specify the isolation level. I did this years ago with a non-threadsafe in-process DLL that needed to be accessed in a threadsafe fashion from IIS and it worked a charm.
Let me know if it works for you :)
Your best bet would be to get the vendor to fix the component. After all, if it won't handle multiple clients, there could be other bugs lurking. If you can't do this, there are some other things to try.
With in-process COM objects I've had occassion to manually load the dll and access the interfaces directly without going through COM.
I haven't done this myself with out-of-process COM, but there are some things you could try. Ultimately the library is just a process sitting there receiving messages which invoke functions.
You might be able to manually start the a new copy of the process for each client and then send it messages. You may run into some hiccups with this. For example, the process may check to see if it's already running and refuse to start or otherwise be unhappy.
If you have a known upper limit on the number of clients, another approach you could consider would be to make multiple copies of the original .exe file and then use binary patching (something similar to the detours library from Microsoft Research) to override the COM registration functions and register each copy as a separate COM object.
Background:
I'm working with a program coded in C++ which uses ODBC on SQL Native Client to establish connections to interact with a SQL Server 2000 database.
Problem:
My connections are abstracted into an object which opens a connection when the object is instantiated and closes the connection when the object is destroyed. I can see that the objects are being destroyed: their destructor are firing and inside of these destructors, SQLDisconnect( ConnHandle ) is being called, followed by SQLFreeHandle( SQL_HANDLE_DBC, ConnHandle ); However, watching the connection count using sp_Who2 or the Performance Monitor in SQL shows the connection count increasing without relent, despite these connections being destroyed.
This hasn't proven problematic until executing a chain of functions that runs long enough to create several thousand of these objects and as such, several thousands of connections.
Question:
Has anyone seen anything like this before? What might be causing this? My initial google searches haven't proven very fruitful!
EDIT:
I have verified that SQLDisconnect is returning without error.
Connection pooling is off. In fact, when I attempt to enabling it using SQLSetEnvAttr, my application crashes when the 2nd call to SQLDriverConnect is made.
Check that you are not using connection pooling. If it is turned on, it will cache opened connections for some (configurable) time.
If you are not using connection pooling, then you must check return value of the SQLDisconnect(). You may have some transaction executing or rollbacking that wont let SQL Disconnect() release your connection.
You have more details on how to check for SQLDisconnect errors at MSDN.
I believe I have seen the same issue in an application that uses MFC and ODBC, rather than the SQL native client API directly. Occaisonally my application hangs on shutdown, the stack trace is:
sqlncli!CCriticalSectionNT::Enter
sqlncli!SQLFreeStmt
sqlncli!SQLFreeConnect
sqlncli!SQLFreeHandle
odbc32!UnloadDriver
odbc32!FreeDbc
odbc32!DestroyIDbc
odbc32!FreeIdbc
odbc32!SQLFreeConnect
mfc42!CDatabase::Close
mfc42!CDatabase::Free
mfc42!CDatabase::~CDatabase
Try as I might, I cannot see anything that might cause such a hang. I'd be grateful if anyone can suggest a solution. It seems others have seen similar issues online, but to date I haven't found any solution.
sqlncli!CCriticalSectionNT::Enter
sqlncli!SQLFreeStmt
sqlncli!SQLFreeConnect
sqlncli!SQLFreeHandle
odbc32!UnloadDriver
odbc32!FreeDbc
odbc32!DestroyIDbc
odbc32!FreeIdbc
odbc32!SQLFreeConnect
mfc42!CDatabase::Close
mfc42!CDatabase::Free
mfc42!CDatabase::~CDatabase
From your stacktrace not having a bottom, can we assume that the CDatabase is a global variable?
Possibly in a dll?
We found your exact symptoms if attempting disconnect from SQL Server from within the destructor of a global variable.
Using the MDAC ODBC drivers works successully.
Moving the code out of the destructor works sucessfully.
It seems something to do with sql native client not liking being called from inside a DllMain.