Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#35 Add ability to override name of DLL to LibraryLoader

1.14 Accepted
closed
nobody
None
7
2008-01-17
2007-12-05
Jason Smith
No

I attached the source file, which I modified from the source in 1.14 M5.

I would like to be able to specify a different DLL name which System.loadLibrary() rather than System.load().

This looks at the system property named "jacob.dll.name" and overrides the default name, which is "jacob", if present.

Very straightforward, very simple, completely backward compatible.

Any chance of getting this into M6?

The motivation behind this is a partial solution to a Scriptom issue that was brought up by FatButtLarry.

Thanks!

Discussion

  • Jason Smith
    Jason Smith
    2007-12-05

    • priority: 5 --> 7
     
  • Jason Smith
    Jason Smith
    2007-12-07

    Logged In: YES
    user_id=1895760
    Originator: YES

    I have revised the previous version to allow specifying the DLL from a resource file (com/jacob/com/LibraryLoader.properties) that must be in the classpath of Jacob's classloader. This resolves an issue that Jacob can be loaded prior to inital programmatic setting of system properties.

    All backward compatibility with the previous version is maintained.

    Thanks!
    File Added: LibraryLoader.java

     
  • clay_shooter
    clay_shooter
    2007-12-08

    Logged In: YES
    user_id=1189284
    Originator: NO

    So you want to change the dll name. Is this so you don't have a conflict with other jacob installations?

    Jacob 1.14 is build with JDK 5. ResouceBundle.containsKey() was introduced with Java 6.

     
  • Jason Smith
    Jason Smith
    2007-12-08

    Logged In: YES
    user_id=1895760
    Originator: YES

    There are two reasons, and please correct me if I get any of this wrong. The first reason is that there are existing versions of Jacob out there, and heck, you can get that with two versions of Groovy! And we have.

    The other reason is that on 64-bit systems, there are two versions of Java that can run. Correct me if I am wrong there. It seems that 32-bit Java will run on 64-bit Windows, and it would require the 32-bit DLL. So for 64-bit Windows, we need to install two DLLs to make sure we covered all the bases.

    The code I attached keeps the old system for Jacob, but gives several new options for specifying a DLL. Existing user's code that redefines the DLL location will not need to be changed.

    Thanks for pointing out the ResourceBundle error. I am surprised the compiler did not pick that up in compatibility mode! I am compiling to 1.5, supposedly. I will resubmit corrected code.

     
  • Jason Smith
    Jason Smith
    2007-12-08

    Logged In: YES
    user_id=1895760
    Originator: YES

    File Added: LibraryLoader.java

     
  • Jason Smith
    Jason Smith
    2007-12-08

    Logged In: YES
    user_id=1895760
    Originator: YES

    Okay, I uploaded a new version which uses "getString()" (oops) and replaces .containsKey() with a call to .getKeys(). It compiles and passes my MINIMAL ability to test this particular functionality.

    Thanks!

     
  • clay_shooter
    clay_shooter
    2007-12-09

    Logged In: YES
    user_id=1189284
    Originator: NO

    Do we want to do this or do we want to change the name of the DLL on each release as part of the build process. Then the LibraryLoader could ask JacobReleaseInfo which version of the DLL it should load.

     
  • Jason Smith
    Jason Smith
    2007-12-10

     
    Attachments
  • Jason Smith
    Jason Smith
    2007-12-10

    Logged In: YES
    user_id=1895760
    Originator: YES

    I was optimizing for backward compatibility. I think the right solution might be to allow the user to specify the DLL in any number of ways, AND maybe Jacob should, by default, use a renamed DLL that is based on the version and the Java VM/OS.

    The code already supported specifying a different DLL, and the new code just takes that idea and runs with it a little. The default that Jacob picks, if nothing else is specified, can be changed now or later without breaking the other parts of the code.

    If you would like me to, I can modify the code to pull the version info from the Jacob manifest for the default. Save you a step. No 1.6 api calls this time. :-)

    Jacob-1.14M99-x86.DLL
    Jacob-1.14M99-x64.DLL
    Jacob-1.14M99-IA64.DLL (is this needed?)

    Another advantage to this is that you don't need to store the DLLs in separate folders. :-)

    Also, uploaded version 3 of the code. :-O I left one reference to a Java 1.6 api in the previous version.
    File Added: LibraryLoader.java

     
  • clay_shooter
    clay_shooter
    2007-12-10

    Logged In: YES
    user_id=1189284
    Originator: NO

    I'll look at integrating your LibraryLoader change into the next milestone but I think the M6 code solves the of the problem you were having.

    The M6 Dll naming convention is jacob<platform>.<version>.dll where version is x86 and AMD64. Your naming convention is jacob-version-platform.dll where the platform is x86 and x64. I like your architecture names better and will change it in the next milestone.

    I hadn't thought about using the manifest. I used the version.properties.

    IA64 is for itanium but there isn't any demand for it.

     
  • Jason Smith
    Jason Smith
    2007-12-10

    Logged In: YES
    user_id=1895760
    Originator: YES

    The architecture names I mentioned were taken from the 3 versions of the Microsoft C++ Runtimes. :-)

    I am still struggling to understand the 64-bit versions of Windows. Does AMD64 also cover the Intel 64-bit chips? Non-Itanium, of course.

    I will wait a bit for you to shake out how you want to set up default naming, and also how to override that. I haven't looked at what's in M6 yet (for some reason it won't download today).

    Thanks!

     
  • clay_shooter
    clay_shooter
    2007-12-10

    Logged In: YES
    user_id=1189284
    Originator: NO

    Wikipedia to the rescue. http://en.wikipedia.org/wiki/X86-64

    I'll rename the AMD64 to x64 in the next milestone.

     
  • Jason Smith
    Jason Smith
    2007-12-10

    Logged In: YES
    user_id=1895760
    Originator: YES

    Very good info! I have added this link to our Scriptom/COM-Scripting wiki as a reference, near the links for the MS C++ libraries. Thanks for taking the time to mention this!

     
  • Jason Smith
    Jason Smith
    2007-12-17

    Logged In: YES
    user_id=1895760
    Originator: YES

    I have had a chance to review the code for JacobLibraryLoader, formerly known as LibraryLoader.

    There are a couple of things that concern me. And you may already be working on these for M7.

    (1) shouldLoad32Bit() and shouldLoad64Bit() should really be combined into one function. The algorithm you have to use here is a "guessing" algorithm, and really should guess between x86, x64, and IA-64 architectures. Java does not provide a clear, standard differentiator. How to guess IA-64? No clue yet.

    (2) Continuing from #1, the implementation that you have in M6 will only work with a SUN JVM. You have to pull in multiple data points to get a "best-guess" for other JVMs.

    (3) I would still like to be able to rebrand the Jacob.DLL. This isn't to hide the fact that I am using Jacob (on the contrary, I advertise it everywhere I can). It is to be able to sync up the version of Scriptom with the version of the Jacob DLL in a meaningful way. It is easier if the files are named Scriptom-1.5.0b6.jar and Scriptom-1.5.0b6.dll, rather than trying to document for every version that you need Jacob-1.14M6.dll, etc.

    The whole point of rolling in the source code and rebranding the DLL is just to make installing newer versions of Scriptom as painless and as foolproof as possible - for users who don't necessarily understand the complexities of Jacob, or DLLs, or the problems that can occur when Jar versions get mixed.

    I'd be happy to roll your ideas (for JacobLibraryLoader) in with my ideas and commit the change (pending your approval of course) if that helps you out. I am open to discussing the design in more detail if you don't agree with what I am saying here. It makes sense to me, but I realize it might not make sense to you. It happens. :-)

    Thanks!

     
  • clay_shooter
    clay_shooter
    2007-12-17

    Logged In: YES
    user_id=1189284
    Originator: NO

    Discussing the default behavior that I'm tried to implement in M6. I'm not to worried about Itanium support at this time. It looks like both the IBM, SUN and GNU JREs (5.0 and above) have a System Property that returns the data model as 32 or 64. The property "sun.arch.data.model" returns 32 or 64. IBM also has a property com.ibm.vm.bitmode. I can change the code to return the number of bits based on sun.arch.data.model.

    Discussing the needs of Scriptom. I'm thinking we could do this in a dependency injection fashion than via (yet another) a system property. We could have a static variable, or a variable on a shared instance, in the JacobLibraryLoader class that contains the name/path to the DLL. Scriptom could insert the name of it's dll into that variable. The current code would be modified to call load() or loadLibrary() based on whether or not there were any "/" charfacters in thepath. In the normal condition, the value would not be set so the current code would run to calculate the name of the library and load it.

     
  • Jason Smith
    Jason Smith
    2007-12-17

    Logged In: YES
    user_id=1895760
    Originator: YES

    I am not worried about Itanium support at this time - just commenting that we should not have a solution that makes it more difficult. :-)

    So you would have a couple of static constants that contains "jacob-1.14M7-##", like:

    . private static String DEFAULT_DLL_NAME_32 = "jacob-1.14M7-32";
    . private static String DEFAULT_DLL_NAME_64 = "jacob-1.14M7-64";

    And it would be my responsibility on the build to find and modify that code to point to a different DLL. Something like that? I guess that simplifies your coding, and it would be simple enough to add to my build script. Sure, I can do that.

     
  • clay_shooter
    clay_shooter
    2007-12-17

    Logged In: YES
    user_id=1189284
    Originator: NO

    The build makes it hard to do exactly what you said because of the way the code figures out the DLL name but we're on the same track. The following snippet assumes Jacob will always calculate the architecture suffix (x86,AMD64,x64)

    ------------- JacobLoadLibrary would have something like. -------------
    private static String JACOB_DLL_BASE_NAME = "jacob"
    private static String JACOB_DLL_VERSION = null;
    private static String JACOB_DLL_ARCH_SUFFIX = null;

    public static void configureJacobDLLComponentNames(baseName,version){
    [[[[code to set the static strings]]]]
    }

    public loadDLLOrWhateverTheMethodIsCalled(){
    if (JACOB_DLL_VERSION == null){
    [[[[[code that looks up version number]]]]]
    [[[[[code that calculates the suffix]]]]]
    jacobDLLName = JACOB_DLL_NAME+"-"+JACOB_DLL_VERSION+"-"+JACOB_DLL_ARCH_SUFFIX+".dll";
    [[[[[load the DLL]]]]]
    }

    --------------- Scriptom code -----------------------------
    init(){
    JacobLoadLibrary.configureJacobDLLComponentNames("Scriptom","1.5.0b6");
    }

     
  • Jason Smith
    Jason Smith
    2007-12-18

    Logged In: YES
    user_id=1895760
    Originator: YES

    This proposed solution still contains a chicken-and-egg problem. What if the user's code also directly addresses Jacob, and does so before Scriptom is loaded? That was the purpose of the embedded properties files in my earlier proposed solution - so that I don't have to assume some part of Scriptom will be loaded first, before Jacob is used.

    And yes, this does happen! :-) It is this way in my current project, and I suspect it would be a problem in many large, old projects that already use Jacob. In my current project, I have code that works directly with Jacob, and I have code that is wrapped in Scriptom. All in the same set of classloaders.

    Solutions (to alleviate chicken-and-egg issue):
    (1) managed through optional properties file (several possible forms)
    (2) maintain a custom version of JacobLibraryLoader
    (3) build process modifies JacobLibraryLoader on the fly

    That's all I can think of.

    But having to call .configureJacobDLLComponentNames() isn't quite what I was looking for. Sorry.

     
  • clay_shooter
    clay_shooter
    2007-12-18

    Logged In: YES
    user_id=1189284
    Originator: NO

    I was trying to avoid another property but understand with your concern and agree the property is the way to go. So I think we want your property code with a modified version of my "determine the dll from the architecture" code. My stuff would run when there is no property set. Do you want to whip up a new loader class or do you want me to merge your previously submitted changes with my code that is in the latest milestone?

    The main changes I'll that need to be made to my piece of the code is to use "sun.arch.data.model" instead of "os.arch", to change AMD64 to x64 and to make the default dll be jacob-(version)-(arch).dll

     
  • clay_shooter
    clay_shooter
    2007-12-18

    Logged In: YES
    user_id=1189284
    Originator: NO

    Scratch some of my comments. I'm already doing this with sun.arch.data.model

     
  • clay_shooter
    clay_shooter
    2007-12-20

    Logged In: YES
    user_id=1189284
    Originator: NO

    Send me an email from an address that accepts attachments (sourceforge accounts don't accept .zip files) and I'll send you M7 for you to verify. I'll push it up when you agree that it works as expected.

     
  • clay_shooter
    clay_shooter
    2008-01-17

    Logged In: YES
    user_id=1189284
    Originator: NO

    Fixed in 1.14 M7

     
  • clay_shooter
    clay_shooter
    2008-01-17

    • milestone: --> 1.14 Accepted
    • status: open --> closed