3 Replies Latest reply on Aug 24, 2018 1:35 PM by Arun Sanbhat

    Loading same dll more than once in a Java JVM

    Arun Sanbhat

      Hi,

       

      We are currently using Java JRE 1.8 u 131 on WINDOWS. We have a java standalone desktop application that loads a C dll for processing of data.This it does by loading the dll using System.LoadLibrary("Name of the dll") function call.

       

      Currently the Java application is single threaded and is processing the data using JNI functions written in C classes inside the dll.

       

      Due to increase in the data by many folds, we would want to make the java application multi-threaded. The C side code does not support multi-threading and cannot be changed due to legacy issues. So we plan to use Java multithreading feature and load the same dll in each thread.

       

      Each thread should process the data separately. However I am not sure if this will work. Can someone please inform me if a dll when loaded by any one of the Java threads, can other thread also be able to load it again? Will the dll would be loaded in a single memory space in the JVM or can each dll will be allocated a separate memory that can be only be accessed by the thread that has loaded it?

        • 1. Re: Loading same dll more than once in a Java JVM
          mNem

          I think, you are better off invoking the code for loading the libraries with start up code for your application.

           

          https://stackoverflow.com/questions/1030792/dll-already-loaded-in-another-classloader

          • 2. Re: Loading same dll more than once in a Java JVM

            The 'short' answer to your question is - YES - it CAN BE done. But it is more complicated than that.

             

            Due to increase in the data by many folds, we would want to make the java application multi-threaded.

            Ok - but it is a BIG mistake if you are settling on a solution before carefully following the standard troubleshooting process which is:

             

            1. identify a problem/issue

            2. confirm that the problem/issue REALLY exists

            3. identify the cause of the problem/issue

            4. identify possible solutions that will eliminate/mitigate the problem/issue

            5. select a small number (2 or 3) of those solutions for prototyping and testing

            6. select the BEST solution from those tested

             

            It isn't clear from what you have posted that you have done ANY of those with the possible exception of #1.

             

            1- what, exactly IS the problem or issue? An 'increase in the data', in and of itself, is typically NOT an issue. The amount of data can often change daily up and down.

             

            More typically it might be the 'performance', or length of time it takes to process the data that becomes problematic.

             

            Is that your problem? Then post DETAILS about the EXACT SLA (service-level agreement) your org has and the details about the performance history of your current app in meeting that SLA.

             

            Did it always meet the SLA until just recently? Does it only miss it now and then? Or every time?

             

            We need facts.

             

            3 - Did you identify the REAL cause of the problem/issue?

            We have a java standalone desktop application that loads a C dll for processing of data.

            What 'processing of data' is the C dll doing? Maybe it is that dll, or the way it does its work, that is the problem.

            The C side code does not support multi-threading and cannot be changed due to legacy issues.

            But that also means it may not properly support being executed multiple times by multiple threads. Some of the processing it does may not work correctly in parallel. A good example (no means the only one) is code that talks to a database and does DML or DDL.

             

            4- post a list of ALL of the possible solutions you have identified. By 'all' I mean list them even if you have ruled them out for some reason. For example one OBVIOUS solution is: write your own code to do the work that C dll currently does - either do the work in Java or write your own dll.

             

            I'm not at all suggesting that 'rewrite' belongs at the TOP of the list of solutions but it is definitely a possible solution. And NO SOLUTION should ever be removed from the list - it should only be prioritized lower on the list.

             

            You'd be surprised how often the lowest priority solution becomes the one that needs to be used because the other 'more desireable' solutions can't be used for some reason.

             

            it should NOT be ruled out or removed -  ones you t

            Due to increase in the data by many folds, we would want to make the java application multi-threaded.

            Well - that COULD BE a possible solution - but it depends on exactly what the real problem is and you haven't really told us yet.

            So we plan to use Java multithreading feature and load the same dll in each thread.

            While possible, if done correctly, that approach has many YELLOW flags and is fraught with potential, and serious problems.

            Each thread should process the data separately.

            Huh? Explain that. Did you mean 'data'? or 'dll'? Do you mean each thread should load the DLL separately?

            However I am not sure if this will work.

            Yes - it CAN work

            No - it won't work

             

            Yes - you can load multiple copies of the same dll if you load them from DIFFERENT physical locations.

             

            No - you can NOT load the same dll from the same PHYSICAL location multiple times.

            Can someone please inform me if a dll when loaded by any one of the Java threads, can other thread also be able to load it again?

            Just answered above.

             

            No - if there is ONE COPY of the dll in ONE LOCATION you can NOT load it multiple times by different threads.

            Will the dll would be loaded in a single memory space in the JVM or can each dll will be allocated a separate memory that can be only be accessed by the thread that has loaded it?

            Sorry - don't take this the wrong way. But that question STRONGLY suggests you don't know how the DLL process works in Windows. And your suggested solution, when appropriate, would only be advisable for an expert.

             

            DLLs are NOT loaded in a JVM per se. They become part of windows but are in the address space of the process that loaded them.

            https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx

            LoadLibrary can be used to load a library module into the address space of the process and return a handle that can be used in GetProcAddress to get the address of a DLL function.

            Loading them into the same address space does NOT mean they are part of the JVM. They are still part of windows itself.

             

            Will the dll would be loaded in a single memory space in the JVM or can each dll will be allocated a separate memory that can be only be accessed by the thread that has loaded it?

            Yes - that can be done. But it requires detailed knowledge of Windows and the DLL process. Done incorrectly can expose you to some real problems in development, testing, actual use and maintenance.

             

            The main complication is ensuring that the DLLs are located and loaded properly and ensuring that the wrong ones are not found/loaded instead of the right ones.

             

            Read that ENTIRE article at the link above. That is just one of many you need to read and understand. But it all boils down to this quote:

            If lpFileName does not include a path and there is more than one loaded module with the same base name and extension, the function returns a handle to the module that was loaded first.

            In a nutshell it CAN BE as simple as:

             

            1. create multiple physical copies of the DLL in different locations - one location/copy for each thread

            2. have each thread do a LoadLibrary call on a DIFFERENT location/dll

            This it does by loading the dll using System.LoadLibrary("Name of the dll") function call.

            That will NOT work. One reason is that the 'name' alone is NOT sufficient to point to DIFFERENT physical copies.

            Both Windows and Java use specific, and sometimes different, search paths to find components to load.

             

            As that quote above says if you just use the name you will get one that is already loaded if one exists with that name. You MUST use path to specify different physical copies.

             

            You can already guess what will happen if, even accidentally, two threads try to use the same one.

             

            If you follow you approach you are going against best practices. For one you are now restricting your application threads to the number of physical files you create.

             

            If you only have THREE dll copies your app won't work properly if it creates more than three threads. That dll copy versus thread correspondence is going to be hard to maintain even if it is documented.

             

            I STRONGLY suggest you identify and revisit all other options before choosing your 'load multiple dll' one.

            1 person found this helpful
            • 3. Re: Loading same dll more than once in a Java JVM
              Arun Sanbhat

              Thanks for your suggestions and informations. Will definitely go through them in detail and see if it can solve our requirement.