epsilonlabs / emc-ptcim

EMC driver for the PTC Integrity Modeler
Eclipse Public License 1.0
2 stars 0 forks source link

Investigate migrating to a 64bit-enabled COM bridge #22

Closed kolovos closed 7 years ago

kolovos commented 7 years ago

Jawin requires a 32-bit JVM, and makes the driver incompatible with other drivers that require a 64-bit environment (e.g. the Simulink driver). We should try to migrate to a less restrictive bridge.

@arcanefoam During your investigation, had you come across http://com4j.kohsuke.org/index.html?

kolovos commented 7 years ago

Jacob (https://sourceforge.net/projects/jacob-project/) could be another option

arcanefoam commented 7 years ago

Just to log out previous discussion, I think that at the end the problem was that I could not manage to use the com4j api to interact with the PTC IM objects. That is, the Jawin API provides a COM object that allows easy invocation of the PTC IM API. I recall nor being able to do this via com4j.

That said, it probably just needs more effort as at the time we were in a hurry ;)

A quick look at Jacob reveals that in this library the base objects are Activex objects. Guess needs testing to see if the PTC IM can be accessed via this abstraction layer.

On 30 Mar 2017 1:40 p.m., "Dimitris Kolovos" notifications@github.com wrote:

Jacob (https://sourceforge.net/projects/jacob-project/) could be another option

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/epsilonlabs/emc-ptcim/issues/22#issuecomment-290385715, or mute the thread https://github.com/notifications/unsubscribe-auth/ACDqba4e0krj12AQBNtDKSUXVKqpywwPks5rq5SlgaJpZM4MaI-k .

zolotas4 commented 7 years ago

In 2745dd0cc55703ca40937534932d22cd38331a66 I created an example of using com4j bridge for ptcim. In this example I just query the COM to get the active project and then it's id. It seems it is working. Am I missing something?

kolovos commented 7 years ago

That's good news! I'd suggest also implementing this minimal example with Jacob (if at all possible) and then running a mini benchmark to see if there's a significant difference in performance before we decide which one to use.

arcanefoam commented 7 years ago

Good news indeed, plus the code looks much cleaner. Definielty need a benchmark to evalute the alternatives.

I would probably also move the generated Interfaces to a separete folder/pacakge to self document their origin.

On Fri, Mar 31, 2017 at 12:46 PM, Dimitris Kolovos <notifications@github.com

wrote:

That's good news! I'd suggest also implementing this minimal example with Jacob (if at all possible) and then running a mini benchmark to see if there's a significant difference in performance before we decide which one to use.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/epsilonlabs/emc-ptcim/issues/22#issuecomment-290680911, or mute the thread https://github.com/notifications/unsubscribe-auth/ACDqbXIRjZNTei3I4vZK0nhfDWCJBrIjks5rrNl_gaJpZM4MaI-k .

zolotas4 commented 7 years ago

Checking the program directory of PTC IM I found that they include the Jacob .dll and .jar files there. So, I believe that Jacob is compatible with PTC IM, I will check that now. Probably Jacob is used for the xmi export (which Stuart told me was developed in York). I asked people to find out who implemented that.

zolotas4 commented 7 years ago

In 72f54e94f358ec76b316c0a177379abbd8aaf749 I created a simple example that uses Jacob to get the id of the active project. I have only tested this for 32-bits - the x86.dll should be placed in C:\Windows\SysWOW64 although it is 32-bit in order to work. I need to change my Eclipse configuration to test 64-bit dll. In general PTC IM is happy with Jacob as well.

kolovos commented 7 years ago

Having to place DLLs in specific folders outside of the Eclipse folder structure is not great for plugin deployment. If Jacob needs this while com4j doesn't, that's a big +1 for com4j in my view.

zolotas4 commented 7 years ago

I agree but I believe that here they code a workaround for that.

zolotas4 commented 7 years ago

(Also confirmed that Jacob is used for the XMI exporter)

kolovos commented 7 years ago

I agree but I believe that here they code a workaround for that.

Fair enough.

zolotas4 commented 7 years ago

Unfortunately, I wasn't able to make neither com4j nor Jacob run succesfully using 64-bit Java. The code compiles and throws an exception when run:

Exception in thread "main" com4j.ExecutionException: com4j.ComException: 80040154 CoCreateInstance failed : Class not registered : .\com4j.cpp:153 (that's from com4j)

I checked the web and all the suggestions fail to fix the problem. I posted a stack overflow question here explaining the situation. My speculation at the moment is that if an application offers only 32-bit dll COM access then it's not possible for Java 64-bit to connect to it.

zolotas4 commented 7 years ago

I can now successfully connect and retrieve data using 64-bit Java and the 32-bit DLL of PTC IM using both Jacob and com4j. The trick suggested in the stackoverflow question I posted works.

Long story short: 32-bit DLLs are not visible by 64-bit Java. However, you can create a surrogate 64-bit DLL (I refer to the dll provided by PTC IM which offers extension points through COM) that will be visible by the 64-bit Java and which delegate to the 32-bit. To do that from you personal machine you can simply ask through the OLE/COM Object Viewer the default ddlhost.exe to act as the surrogate for the 32-bit DLL (that's what I have done). Of course, this means that users have to do the same manually in their machines which is not handy. The stackoverflow user suggested 2 approaches that work if we don't want users to do this process manually (so what we should do when we will distribute the driver). I did a quick research and people suggest that these approaches might be very simple and straightforward or sometimes very complicated and might require more effort than actually building a new 64-bit dll for the application. I personally have not previous exposure to any of these technologies so I can't comment how difficult it will be for PTC IM - it might be possible to do it in a few minutes (really, I have no idea at the moment). I will investigate soon but for now as I can run it using the local trick, I will run a small scale benchmarking to check which of the two (com4j vs Jacob) is faster and then proceed with finding ways to build the surrogate DLL.

kolovos commented 7 years ago

Could the surrogate 64bit DLL approach also work for Jawin?

kolovos commented 7 years ago

For what's worth, in this SO thread two of the participants report that Jacob leaks more memory than com4j, which could be an important concern for long-running processes (e.g. when we support incrementality)

zolotas4 commented 7 years ago

For what's worth, in this SO thread two of the participants report that Jacob leaks more memory than com4j, which could be an important concern for long-running processes (e.g. when we support incrementality)

I have read that in other posts as well.

Could the surrogate 64bit DLL approach also work for Jawin?

I don't know the answer now. My understanding is that Jawin can only connect to Win32 so it won't be able to view 64bit dlls. I am not even sure if a 64-bit Jawin exists. I need to investigate.

zolotas4 commented 7 years ago

In 07fdc3e95c2b067c91106ac6c4bf887c3458cacc and 50013fcafd5ebea58cd65258468e45e8b3fd21ce I created benchmarks for Jawin 32-bit, Jacob 32-bit and 64-bit, com4j 32-bit and 64-bit. There's no significant difference among the 5 benchmarks.

Could the surrogate 64bit DLL approach also work for Jawin?

As far as I can tell Jawin is not compatible at all with Java 64-bit. It throws the exception Can't load IA 32-bit .dll on a AMD 64-bit platform which is a result of not using Java 32-bit. An answer in SO suggests that this error can be solved by recompiling the DLL of interest (Jawin.dll in this case) to 64-bit but I don't know if that's possible with Jawin.

kolovos commented 7 years ago

OK - it looks like we should not consider Jawin any further (we don't want to have to compile / maintain our own 64-bit version if other alternatives are viable). Regarding the benchmark, a quick look at the code reveals that it performs 100 iterations. It'd be useful to bump this up to e.g. 10K or 100K before we reach a decision.

zolotas4 commented 7 years ago

The following are the timings for 10K runs of each approach (2 repetitions).

Approach 32-bit (1st/2nd repeat) 64-bit (1st/2nd repeat)
com4j 296 / 304 sec 311 / 322 sec
Jacob 304 / 312 sec 315 / 322 sec
Jawin 285 / 297 sec - / -

Pros and cons for Jacob & com4j Jacob: +Easy casting +Jawin like syntax -We need to program the selection of 32/64-bit dll at so it picks the correct at runtime -Syntax (as Jawin's) is not as clean as com4j's -More memory leak vs com4j

com4j: +Clean syntax +Automatic selection of the appropriate .dll at runtime -Casting is done through a .queryInterface() method which might have impact in the performance at long run

kolovos commented 7 years ago

Shall we go with com4j then?

zolotas4 commented 7 years ago

Moved to com4j.