Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (577)
games submitted by our members
Games in WIP (498)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Dynamic loading of the .DLLs - hitting a snag  (Read 5951 times)
0 Members and 1 Guest are viewing this topic.
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Posted 2005-07-25 15:49:28 »

Hey, guys.

I'm trying to dynamically load the libs for jOGL in code so as not to require a -classpath/-Djava.library.path command line issue.

This is the function as I have it right now:

/** Load the appropriate libraries for the JOGL bindings.
     *  @param iOS An operating system constant (see above in GameFrame.java) */
    public static void loadGL(int iOS)
    {
        try
        {
            URL urlJOGL = (new File(Tools.GetRelativePath(null) + Tools.GetFileSeparator() + "jogl.jar")).toURL();
            URL[] urls = { urlJOGL };
            new URLClassLoader(urls);
        }
        catch (MalformedURLException exc) { /* TODO: Log */ }                               
 
        String strJOGL = Tools.GetRelativePath("org.slage.ui.jogl.");
        switch (iOS)
        {
            case WIN32:               
                System.load(strJOGL + "jogl.dll");
                System.load(strJOGL + "jogl_cg.dll");               
                break;
            case LINUX:
                System.load(strJOGL + "libjogl.so");
                System.load(strJOGL + "libjogl_cg.so");
                break;
            case MACOSX:
                System.load(strJOGL + "libjogl.jnlib");
                System.load(strJOGL + "libjogl_cg.jnlib");
                break;
            case SOLARIS_SPARC:
                System.load(strJOGL + "libjogl_solsparc.so");
                break;
            case SOLARIS_X86:
                System.load(strJOGL + "libjogl_solx86.so");
                break;
        }       
   
    }
   
Note: I renamed the solaris .so files so they would all have unique filenames; not sure if this will be an issue or not.

When I run this code, I get a message box from java.exe that tells me "A required DLL, jawt.dll, is not found.." etc. I checked my JRE and JDK directories; sure enough, it's there. I also ran another AWT/Swing app to verify that it's working. So, something in my code has to be causing this issue.

Does anyone have any suggestions on how to fix the problem, or another method for solving the dynamic loading quandary? Huh
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #1 - Posted 2005-07-25 18:56:57 »

See the NativeLibLoader in the JOGL workspace. We've found it necessary to preload JAWT on most platforms to work around problems with that DLL not being in the user's PATH.
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #2 - Posted 2005-07-26 05:01:39 »

I see that it's trying to load it, but I don't know what to do about the fact that it's failing.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #3 - Posted 2005-07-26 07:56:25 »

The manual loading of the JAWT via System.loadLibrary("jawt") doesn't fail. It works around the fact that loading JOGL (which depends on JAWT) doesn't work on most platforms unless the JAWT has been dynamically loaded first.
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #4 - Posted 2005-07-26 14:50:34 »

OK... I did this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
  static 
    {        
        // First, load in the JOGL.jar file
       try
        {
            URL urlJOGL = (new File(Tools.GetRelativePath(null) + Tools.GetFileSeparator() + "jogl.jar")).toURL();
            URL[] urls = { urlJOGL };
            new URLClassLoader(urls);
        }
        catch (MalformedURLException exc)
        {
            // TODO: Log
           System.err.println("MalformedURLException while loading jogl.jar");
        }                                
 
        // Manually load AWT to work around the problem with it not finding it
       System.loadLibrary("awt");
        System.loadLibrary("jawt");
       
       
        // Now, load the .dll/.so files for the OpenGL C bindings
       String strOS = Tools.GetOS();
        String strJOGL = Tools.GetRelativePath("org.slage.ui.jogl.");
       
        if (strOS.startsWith("Windows"))
        {
            System.load(strJOGL + "jogl.dll");
            System.load(strJOGL + "jogl_cg.dll");                
        }        
        if (strOS.startsWith("Mac OS X"))
        {
              System.load(strJOGL + "libjogl.jnlib");
              System.load(strJOGL + "libjogl_cg.jnlib");        
        }        
    }


I'm now getting a new error box:

"The procedure entry point cgNextParameter_depr_1_1 could not be loaded in the dynamic link library cg.dll."

I've tried System.loadLibrary("cg"); and it doesn't help at all.

Any suggestions?
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #5 - Posted 2005-07-26 17:40:21 »

What version of Cg are you using? It looks like those functions were present in the 1.3 release of Cg and are absent in the current 1.4 release.

We would probably have to release another version of JOGL to bring it up to date with Cg 1.4. I'm a little reluctant to do that right now because it is becoming a maintenance problem preventing us from doing work on the JSR-231 APIs. Can you find a copy of the Cg 1.3 runtime?
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #6 - Posted 2005-07-26 23:59:34 »

As it stands, I have Cg 1.4 installed, but I'm not using Cg at all in this or any other project. I just installed it to play around with it one day. If I need Cg in order to make jOGL work, I'll get whatever version is needed, but if I don't plan on using Cg, could I just disable it or uninstall the runtime?
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #7 - Posted 2005-07-27 01:40:51 »

Yes, you can disable it -- just don't load the jogl_cg native library. You'll get an UnsatisfiedLinkError if you later try to use Cg routines. We'll upgrade JOGL to Cg 1.4 in the JSR-231 source tree.
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #8 - Posted 2005-07-28 16:26:05 »

Well, we're getting closer.

Taking out the Cg stuff, I now can't get the .jar file to dynamically load before it tries to create a subclass of its contents, so it's throwing a NoClassDefFound. As it stands, the following code is in a static {} block in the class where main() is executed.

1  
2  
3  
4  
5  
6  
7  
        try
        {
            URL urlJOGL = (new File(Tools.GetRelativePath(null) + Tools.GetFileSeparator() + "jogl.jar")).toURL();
            URL[] urls = { urlJOGL };
            new URLClassLoader(urls);
        }
        catch (MalformedURLException exc)


So, trying to see what would happen, I commented this part out and then loaded the .jar using the -classpath command line option. When I did, I'm now getting an UnsatisfiedLink because awt.dll is already loaded. This is where I'm loading the .dll files:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
// Manually load AWT to work around the problem with it not finding it         
       System.loadLibrary("awt");
        System.loadLibrary("jawt");        
       
        // Now, load the .dll/.so files for the OpenGL C bindings
       String strOS = Tools.GetOS();
        String strJOGL = Tools.GetRelativePath("org.slage.ui.jogl.");
       
        if (strOS.startsWith("Windows"))
        {
            System.load(strJOGL + "jogl.dll");
            if (bLoadCg)
                System.load(strJOGL + "jogl_cg.dll");                
        }        
        if (strOS.startsWith("Mac OS X"))
        {
              System.load(strJOGL + "libjogl.jnlib");
              if (bLoadCg)
                System.load(strJOGL + "libjogl_cg.jnlib");        
        }        


You only told me to loadLibrary on jawt.dll, but when I did, I started getting error boxes that it couldn't find awt.dll either, and adding that line stopped those boxes. Presumably, I now have to find a way to tell the JVM not to load AWT again.

Sorry to be such a pain.

Offline Ken Russell

JGO Coder




Java games rock!


« Reply #9 - Posted 2005-07-28 17:45:09 »

Please post stack traces for some of the exceptions you're seeing. I suspect the NoClassDefFoundError is occurring because of the delegation path of your class loaders. If you make a subordinate class loader to load JOGL and are trying to load classes which reference JOGL then those classes must be loaded from the same loader or a subordinate loader of the other one, because otherwise the "current" class loader (the one which your subordinate loader will delegate to by default) won't know how to find the JOGL classes. Class loader delegation occurs up to the parent loader, not down to the child loader.

You need to call Toolkit.getDefaultToolkit() before trying to manually System.loadLibrary("jawt"). Do not call loadLibrary("awt"). It is loaded by the boot loader and loading it manually will break the JDK's internal loading of it as you've found.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #10 - Posted 2005-08-02 08:51:53 »

OK. Ignoring the jar for a minute (I can handle the classloader later...), I'm getting UnsatisfiedLinks on jogl.dll when I try to dynamically load it, now. Here's the code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
  // this is called from a static initializer block in the class where main() is 
 public static void loadOpenGL()
    {        
        // Manually load AWT to work around the problem with error boxes coming up claiming it's not found.
       // Apparently AWT has to be loaded -before- jogl's .dll files or all Hell breaks loose.
       java.awt.Toolkit.getDefaultToolkit();
        System.loadLibrary("jawt");                        
         
        // Now, load the .dll/.so files for the OpenGL C bindings
       String strOS = Tools.GetOS();
        String strJOGL = Tools.GetRelativePath("lib") + Tools.GetFileSeparator();                
       
        if (strOS.startsWith("Windows"))
        {                        
            System.load(strJOGL + "jogl.dll");            
           
            if (bLoadCg)
                System.load(strJOGL + "jogl_cg.dll");                
        }        
        if (strOS.startsWith("Mac OS"))
        {
              System.load(strJOGL + "libjogl.jnlib");
              if (bLoadCg)
                System.load(strJOGL + "libjogl_cg.jnlib");        
        }                
        if (strOS.startsWith("Linux"))
        {
                System.load(strJOGL + "libjogl.so");
                if (bLoadCg)
                    System.load(strJOGL + "libjogl_cg.so");
        }
        if (strOS.startsWith("Solaris"))
        {
               String strArch = System.getProperty("os.arch");
               if (strArch.equalsIgnoreCase("sparc"))
               {
                   System.load(strJOGL + "libjogl_solsparc.so");
               }
               if (strArch.equalsIgnoreCase("x86"))
               {
                   System.load(strJOGL + "libjogl_solx86.so");
               }
        }
    }


And this is the exception trace I get:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
Exception in thread "main" java.lang.UnsatisfiedLinkError: no jogl in java.library.path
        at java.lang.ClassLoader.loadLibrary(Unknown Source)
        at java.lang.Runtime.loadLibrary0(Unknown Source)
        at java.lang.System.loadLibrary(Unknown Source)
        at net.java.games.jogl.impl.NativeLibLoader$1.run(NativeLibLoader.java:72)
        at java.security.AccessController.doPrivileged(Native Method)
        at net.java.games.jogl.impl.NativeLibLoader.load(NativeLibLoader.java:58)
        at net.java.games.jogl.impl.GLContext.<clinit>(GLContext.java:52)
        at net.java.games.jogl.impl.windows.WindowsGLContextFactory.createGLContext(WindowsGLContextFactory.java:147)
        at net.java.games.jogl.GLCanvas.<init>(GLCanvas.java:72)
        at net.java.games.jogl.GLDrawableFactory.createGLCanvas(GLDrawableFactory.java:150)
        at net.java.games.jogl.GLDrawableFactory.createGLCanvas(GLDrawableFactory.java:118)
        at net.java.games.jogl.GLDrawableFactory.createGLCanvas(GLDrawableFactory.java:85)
        at org.slage.ui.GameFrame.<init>(GameFrame.java:84)
        at org.slage.SLAGE.initialize(SLAGE.java:94)
        at org.slage.tests.ImageTest.main(ImageTest.java:41)


All I want to do is get the dlls and jars loading in such a way as to prevent a lot of command line switches. It seems that I shouldn't be the first person to have wanted to do this - what am I missing here?
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #11 - Posted 2005-08-02 17:11:40 »

Calling net.java.games.jogl.impl.NativeLibLoader.disableLoading() before doing any JOGL-related operations will avoid the exception above.

In the past two years there has only been one other request to do something similar to what you're doing (which is why the enableLoading/disableLoading methods are exposed). I think most people are deploying JOGL apps with Java Web Start which takes care of this automatically. During development it isn't difficult to write some simple wrapper scripts which set up either the PATH/LD_LIBRARY_PATH/CLASSPATH environment variables or -Djava.library.path/-classpath.
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #12 - Posted 2005-08-02 17:30:57 »

That did it! Once I get the .jar loading situation handled with a classloader, I'm all set.

You really are a 'ninja', Ken. Thanks much.
Offline Soulfly32

Senior Newbie





« Reply #13 - Posted 2005-08-02 18:03:19 »

HI, i am also interested in dynamically loading those libs.
Want to use this for my engine. Tried this many times but no.
Will there maybe a built-in LibLoader in JSR-231 or standart loader?

_____________________________________
www.soulfly-design.de
www.soulflyhome.com
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #14 - Posted 2005-08-02 18:24:35 »

Feel free to file a Request for Enhancement using the JOGL Issue Tracker.
Offline Soulfly32

Senior Newbie





« Reply #15 - Posted 2005-08-02 19:39:28 »

Can you tell me what the Tools class is.

_____________________________________
www.soulfly-design.de
www.soulflyhome.com
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #16 - Posted 2005-08-02 19:40:05 »

Consider it done:

https://jogl.dev.java.net/issues/show_bug.cgi?id=171
https://jogl.dev.java.net/issues/show_bug.cgi?id=172

Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #17 - Posted 2005-08-02 19:43:56 »

It's just a bunch of static utilities I wrote. Nothing major.

Here's a version of the code, which now works, with the Tools calls replaced with straight java:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
/** Static initialization  - load libraries */
      /** Ensure we load GL on startup. This is a replacement for the command-line switches
     *  -Djava.library.path=.
     *
     *  @param bLoadCg if 'true', load Cg libraries
     */

    public static void loadOpenGL(boolean bLoadCg)
    {        
        // workaround to allow our loader to do its job
       // see http://192.18.37.44/forums/index.php?topic=10262.0;topicseen
       net.java.games.jogl.impl.NativeLibLoader.disableLoading();
       
        // Manually load AWT to work around the problem with error boxes coming up claiming it's not found.
       // Apparently AWT has to be loaded -before- jogl's .dll files or all Hell breaks loose.
       java.awt.Toolkit.getDefaultToolkit();
        System.loadLibrary("jawt");        
       
        // Now, load the .dll/.so files for the OpenGL C bindings
       String strOS = System.getProperty("os.name");
        String strJOGL = System.getProperty("user.dir") + System.getProperty("file.separator") + "lib" +
                System.getProperty("file.separator");
       
        if (strOS.startsWith("Windows"))
        {                        
            System.load(strJOGL + "jogl.dll");            
           
            if (bLoadCg)
                System.load(strJOGL + "jogl_cg.dll");                
        }        
        if (strOS.startsWith("Mac OS"))
        {
              System.load(strJOGL + "libjogl.jnlib");
              if (bLoadCg)
                System.load(strJOGL + "libjogl_cg.jnlib");        
        }                
        if (strOS.startsWith("Linux"))
        {
                System.load(strJOGL + "libjogl.so");
                if (bLoadCg)
                    System.load(strJOGL + "libjogl_cg.so");
        }
        if (strOS.startsWith("Solaris"))
        {
               String strArch = System.getProperty("os.arch");
               if (strArch.equalsIgnoreCase("sparc"))
               {
                   System.load(strJOGL + "libjogl_solsparc.so");
               }
               if (strArch.equalsIgnoreCase("x86"))
               {
                   System.load(strJOGL + "libjogl_solx86.so");
               }
        }
    }
 
Offline Tomas

Junior Member




Agency9


« Reply #18 - Posted 2005-08-04 00:47:59 »

Could this line of tought be extended so that the .so and .dll libs are loaded directly from a .jar ? And would it be possible to bake cg.dll (The Cg runtime) inside the .jar aswell ?

// Tomas Smiley

CTO Agency9
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #19 - Posted 2005-08-04 02:27:11 »

It is not possible to System.load() a shared object directly from within a jar file. At a minimum it would have to be unpacked on to the local disk.
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #20 - Posted 2005-08-04 04:16:29 »

How's about just a static call, passing in the path to your lib directory?
Offline Tomas

Junior Member




Agency9


« Reply #21 - Posted 2005-08-04 11:53:35 »

Quote
It is not possible to System.load() a shared object directly from within a jar file.

Bugger.  Like I expected then.

Quote
At a minimum it would have to be unpacked on to the local disk.

I don't know if that solution would be any better than just shipping the natives unpacked and I guess that java doesn't allow you to mount a virtual filesystem in RAM memory either ?

// Tomas

// Tomas


CTO Agency9
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #22 - Posted 2005-08-04 14:41:55 »

I don't know if that solution would be any better than just shipping the natives unpacked and I guess that java doesn't allow you to mount a virtual filesystem in RAM memory either ?

It would still enable them to make a function to load the libs dynamically for the right os without the user needing to use -Djava.library.path.

Incidentally, does anyone know of a way to do the noddraw workaround in code?
Offline Tomas

Junior Member




Agency9


« Reply #23 - Posted 2005-08-04 15:48:44 »

True.

CTO Agency9
Offline pepijnve

Junior Member




Java games rock!


« Reply #24 - Posted 2005-08-04 16:21:50 »

I suggested some extracting/loading procedure to someone a while ago http://192.18.37.44/forums/index.php?topic=10074.msg79958#msg79958
Still haven't tried it though. Maybe if you combine it with File#deleteOnExit to avoid littering the disk with libraries it might work Smiley
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #25 - Posted 2005-08-04 18:42:19 »

Ken, we're still having trouble, with the code posted above, getting jawt loaded on OS X. Any more suggestions from your bag of tricks?
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #26 - Posted 2005-08-04 22:49:37 »

Ken, we're still having trouble, with the code posted above, getting jawt loaded on OS X. Any more suggestions from your bag of tricks?

Could you please post the exception stack trace?
Offline Jaeden

Senior Newbie




There is no knowledge that is not power.


« Reply #27 - Posted 2005-08-04 23:15:55 »

Sure, as soon as my tester with the Mac gets online Smiley
Offline judit.papp

Innocent Bystander





« Reply #28 - Posted 2005-08-31 15:10:32 »

Hello,
Thank you very much for the useful info you provide.
I tried the dynamic loading of the native libraries, and it works fine under windows and linux.

I had a problem on mac, but finally I managed to figure it out.
So it works now on mac as well!
The difference from Jaeden's code is, that I do not load jawt on mac.
I had a lot of trouble from mismatching versions of jar and native files.
Hope this helps.
Offline bumpert

Senior Newbie




Java games rock!


« Reply #29 - Posted 2006-05-03 15:01:47 »

Hi,
   i'm trying to do the same things by loading the DLLs and the jar file from my code but i'm not able.

Here is the code i use (same as Jaeden):

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
        //Allow loader
       NativeLibLoader.disableLoading();

        //Seems to have to load awt first
       java.awt.Toolkit.getDefaultToolkit();
        System.loadLibrary("jawt");
       
        //Load the jogl jar file
       URL urlJOGL = (new File(ThinClient.getPath() + "jogl.jar")).toURL();
        URL[] urls = { urlJOGL };            
        URLClassLoader classLoader = new URLClassLoader(urls);

        //Load the DLLs
       System.load(ThinClient.getPath() + "jogl.dll");
        System.load(ThinClient.getPath() + "jogl_awt.dll");


After this, i'm getting this error

1  
2  
java.lang.NoClassDefFoundError: com/sun/opengl/impl/NativeLibLoader
...


It was like if my jar wasn't loaded. Anybody have an idea?

I want to do this cause on Windows i'm able to put the jar into the lib/ext folder and the DLLs into the bin folder of the JRE the first time, but i need a cross platform solution. On Linux i can't do this, cause the JRE folders are 99% with root acces, so i cannont use this method with normal user. This solution seems good cause i put the files into the home directory of the user (i'll adapt the code for others os after i'll be able to load the stufss dynamically).

thx a lot!!!
Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (23 views)
2014-04-15 18:08:23

BurntPizza (18 views)
2014-04-15 03:46:01

UprightPath (32 views)
2014-04-14 17:39:50

UprightPath (16 views)
2014-04-14 17:35:47

Porlus (32 views)
2014-04-14 15:48:38

tom_mai78101 (58 views)
2014-04-10 04:04:31

BurntPizza (116 views)
2014-04-08 23:06:04

tom_mai78101 (216 views)
2014-04-05 13:34:39

trollwarrior1 (183 views)
2014-04-04 12:06:45

CJLetsGame (190 views)
2014-04-01 02:16:10
List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:05:20
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!