How to use JACOB dll in Wisdom application ?

574 views
Skip to first unread message

Nicolas Delsaux

unread,
Mar 15, 2016, 7:33:53 AM3/15/16
to wisdom-...@googlegroups.com
Hi,
I have a wisdom application in which I want to interact with Microsoft
Office. For that, I've added to my pom the various requirements of JACOB
(both the JAR and the DLL).
However, it seems that it's not enough to have the dll added to my
java.library.path during wisdom run, as I get explicit error messages
from JACOB telling me it"s not the case.

So, when using Wisdom, what is the best way to have a DLL integrated in
java.library.path ?

Thanks

--
Nicolas Delsaux

Nicolas Rempulski

unread,
Mar 15, 2016, 7:56:28 AM3/15/16
to wisdom-...@googlegroups.com
Hi Nicolas,

I can't answer you exactly with the combo dll/JACOB but I can share with you a native packaging that is working for us.

We use this OpenCV packaging : https://github.com/openpnp/opencv

The part that is relevant to you should be : 

The "trick" is to extract the dll to a given temp directory and load it from there.

In our case, we "load" OpenCV through a specific class (not sure it should be a @Component, ... dirty code ) : 

@Component
@Instantiate
public class OpenCVLoader {
    static{
        OpenCV.loadLocally();
    }
}

Hope this will help you.



--
Nicolas Delsaux

--
You received this message because you are subscribed to the Google Groups "wisdom-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wisdom-discus...@googlegroups.com.
Visit this group at https://groups.google.com/group/wisdom-discuss.
To view this discussion on the web visit https://groups.google.com/d/msgid/wisdom-discuss/56E7F31F.3090500%40gmx.fr.
For more options, visit https://groups.google.com/d/optout.

Nicolas Delsaux

unread,
Mar 17, 2016, 8:31:52 AM3/17/16
to wisdom-...@googlegroups.com
Unfortunatly, JACOB do not have such a nice method.
So i tried locating the dll in CLASSPATH ... using System.getProperty(...) which only returned bin/chameleon.jar

So, now, i'm trying to lcoate it using MyClass.getClassLoader().getResource(...), but when I use as resource path "jacob-1.18-x64.dll", I get nothing. Maybe (I guess) because my dll dependency may not be added to CLASSPATH by Wisdom (cause it's a dll, not a jar).
So, how can i make sure my dll appear in Wisdom classpath ?
And is the resource path I use correct ?

Nicolas Rempulski

unread,
Mar 17, 2016, 6:06:50 PM3/17/16
to wisdom-...@googlegroups.com
There are several things here, and I'm not really proficient with Java / Native binding. Take what I will say with a grain of salt.

Native library loading works with PATH to find files (java.library.path property), not with CLASSPATH. You should try to export your native library path in PATH before launching Wisdom, and try to System.loadLibrary('jacob-1.18-x64"). 
You could also try System.load("C:\path\to\native\library\jacob-1.18-x64.dll");

If this fail, you will have to build promatically the path to your library.
I think the first thing to know is where is located the native library relatively to your application. 
- Will it be embedded in your jar ? 
- Located in the filesystem relative to your application launch path ? 
- Elsewhere in the system ?

I tend to prefer to package the native library inside the jar as it ensures it will be deployed with the application and ready to use without configuration on the host system. But it complexify the loading because you have to extract the library from the jar before using it.

I think a hardcoded path is a first step, once it will work you could seek to embed it in your jar.


try {
System.loadLibrary("jacob-1.18-x64");//


} catch (final UnsatisfiedLinkError ule) {




this.libraryPath = "/path/to/native/";
addLibraryPath(libraryPath.getParent());
System.loadLibrary("jacob-1.18-x64"); 

}
}

The first loadLibrary will work if the path to your library is in PATH, if not it will force your path into PATH and retry to loadLibrary.

Hope this help!

Nicolas Delsaux

unread,
Mar 18, 2016, 8:07:51 PM3/18/16
to wisdom-...@googlegroups.com
According to OSGi documentation, it seems that, to load a native library, one need to add the "Bundle-NativeCode" with informations about the various dll in the src/main/osgi/osgi.bnd file.
That' what I did with the following code.

Bundle-NativeCode: jacob-1.18-x86.dll ; osname=Win7 ; osname=win32 ; processor=x86
Bundle-NativeCode: jacob-1.18-x64.dll ; osname=Win7 ; osname=win32 ; osname=win64 ; processor=x86_64

Unfortunatly, this doesn't work, since when I try to start jacob, it doesn't work with the following exception

[1;31m[ERROR]     wisdom-error [0;39m [36m{vert.x-eventloop-thread-0} [0;39m - An exception occurred while processing request POST /skillCenter/{portal}/config/add
java.lang.UnsatisfiedLinkError: no jacob-1.18-x64 in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865) ~[na:1.8.0_31]
    at java.lang.Runtime.loadLibrary0(Runtime.java:870) ~[na:1.8.0_31]
    at java.lang.System.loadLibrary(System.java:1119) ~[na:1.8.0_31]

Which is quite weird.

So. what did I did wrong ?

Nicolas Delsaux

unread,
Mar 20, 2016, 1:52:45 PM3/20/16
to wisdom-...@googlegroups.com
To go a little further, if the syntax below didn't work, chaning it to


Bundle-NativeCode: jacob-1.18-x86.dll;osname=Win7;osname=win32;processor=x86
Bundle-NativeCode: jacob-1.18-x64.dll;osname=Win7;osname=win64;processor=x86_64

the second line seems to resolve in ManifestParser to the following bundle requirement string

[[51.1] osgi.native; (&(|(osgi.native.osname~=win7)(osgi.native.osname~=win64))(osgi.native.processor~=x86_64))]

Unfortunatly, a little debug of ManifestParser reveals that the ManifestParser#m_configMap do not contain the osgi.native.osname property, neither the osgi.native.processor. So ... what am i doing wrong ? Is there any OSGi expert in the room to help me ?

Oh the craziness !
It was just "Win32" instead of win32, and "Win32" even for Windows running on 64bits hardware. Changing that made the library being correctly recognized as a native bundle. Hopefully, the OSInformation class contained all the variables I would need to understand the problem.

However, even with that, I still have jacob failing to load that library ... even with unfortunatly the exact same message I have from the beginning :


java.lang.UnsatisfiedLinkError: no jacob-1.18-x64 in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865) ~[na:1.8.0_31]
    at java.lang.Runtime.loadLibrary0(Runtime.java:870) ~[na:1.8.0_31]
    at java.lang.System.loadLibrary(System.java:1119) ~[na:1.8.0_31]
    at com.jacob.com.LibraryLoader.loadJacobLibrary(LibraryLoader.java:184) ~[jacob-1.18.jar:na]

I'm quite puzzled now, and will try again later on ...

Clement Escoffier

unread,
Mar 21, 2016, 3:53:29 AM3/21/16
to wisdom-...@googlegroups.com
Hi,

It looks like your native library is loaded using the regular java way. So, you would need to add the native library in a directory specified using the java.library.path property. On windows this path is the PATH, so you probably will have to put your library and its dependencies somewhere in the PATH (current directory won’t work). I remember having to install the libraries in system32 to get it to work. 

Clement


Nicolas Delsaux

unread,
Mar 21, 2016, 12:56:42 PM3/21/16
to wisdom-...@googlegroups.com


Le 20/03/2016 18:52, Nicolas Delsaux a écrit :
To go a little further, if the syntax below didn't work, chaning it to

Bundle-NativeCode: jacob-1.18-x86.dll;osname=Win7;osname=win32;processor=x86
Bundle-NativeCode: jacob-1.18-x64.dll;osname=Win7;osname=win64;processor=x86_64

the second line seems to resolve in ManifestParser to the following bundle requirement string

[[51.1] osgi.native; (&(|(osgi.native.osname~=win7)(osgi.native.osname~=win64))(osgi.native.processor~=x86_64))]

Unfortunatly, a little debug of ManifestParser reveals that the ManifestParser#m_configMap do not contain the osgi.native.osname property, neither the osgi.native.processor. So ... what am i doing wrong ? Is there any OSGi expert in the room to help me ?

Oh the craziness !
It was just "Win32" instead of win32, and "Win32" even for Windows running on 64bits hardware. Changing that made the library being correctly recognized as a native bundle. Hopefully, the OSInformation class contained all the variables I would need to understand the problem.


Yeah, and don't forget that line-return character at end of line, cause it caused most of the bugs I had.
Now i've added it, I only have a NoClassDefFoundError on one of jacob classes :

java.lang.NoClassDefFoundError: Could not initialize class com.jacob.activeX.ActiveXComponent
    at org.capgemini.admdt.kpitv.helpers.loaders.powerpoint.MSPowerPoint.transform(MSPowerPoint.java:160) ~[na:na]
    at org.capgemini.admdt.kpitv.helpers.loaders.powerpoint.SlideshowLoader.loadInnerContentOf(SlideshowLoader.java:38) ~[na:na]
    at org.capgemini.admdt.kpitv.helpers.loaders.AbstractPageFromFileLoader.loadContentOf(AbstractPageFromFileLoader.java:64) ~[na:na]
    at org.capgemini.admdt.kpitv.helpers.loaders.AbstractPageFromFileLoader.load(AbstractPageFromFileLoader.java:31) ~[na:na]


Well ... it appears this bug appear at reload time ... very weird.
Reply all
Reply to author
Forward
0 new messages