Hello, everyone. I want to thank everyone for their help and input. I
believe I have solved the problem using a hack that works in my
particular case. If you are not interested in the hack itself, you can
stop reading here with my thanks.

In my particular case, calls to the server would be rare and pretty
much always dominated time-wise by the transfer of data between the
client and server. I think this is probably a very common if not
ubiquitous situation in web development and so I thought I'd let
everybody know why it was so hard to deal with and what the workaround
is. I was attempting to link a native library statically to a java
native interface.

On some systems, this might be easy but I am working in Windows using
Visual Studio for compilation (theme to Jaws starts playing now)
because the compiled native code is so much faster than the equivalent
Netbeans or Eclipse code. When you compile in C/C++ with Visual Studio
using the default settings, the library that you compile is linked
dynamically at run-time to various other libraries in the Windows
system (including some that are compiler dependent). The paths to
these files are encoded within the manifest; unfortunately, then, when
you try to port your code to another machine, your links are likely no
longer correct. You might think that the solution would be to simply
recompile on the new machine or maybe statically link some libraries
into the code. This may work in some cases but not this one. Even if
everything is linking correctly and the java.library.path is set to
find your library, Windows itself needs to know where to look for the
additional libraries that link to yours at run-time because it is
Windows that is doing the linking and not Java; Java does the initial
search for the library, but if your library requires other libraries
(and most do), then Windows is stuck without major changes to the path
environment variable via searches using Dependency Walker or some
other similar tool. I've read that this is referred to in "stud"
programming circles as "Windows DLL Hell" and it's one of those
situations where the easiest thing to do might be to just reprogram
the thing in Java. I cannot do that due to (a) the size of code and
(b) the necessity for the speed of native code.

The workaround is simple but nonintuitive. Rather than link the native
code statically to the Java program itself, one can use a Windows
system prompt to run an executable. It is a simple matter to write a
wrapper for a native DLL in native code that is an executable rather
than a library. In Java, capture the output to the executable using
the instructions on the following web site:
http://www.rgagnon.com/javadetails/java-0014.html
You're essentially simulating the DLL using an executable wrapper.

I know that this is horribly inefficient from a programming point of
view and may waste as much as a significant fraction of a second, but
when the call is being made by a client and the transfer time plus
execution time of the code is on the order of potentially an entire
second or more, this is the easiest thing to do. (Obviously, that
final statement is an opinion only.)

Anyway, I hope this winds up helping somebody out there, and I greatly
appreciate all the help that was generously offered me. Best to
everyone, Darin

On Nov 5, 8:01 am, Yegor <[email protected]> wrote:
> Darin,
>
> Maybe what you are really looking for ishttp://code.google.com/p/nativeclient/
> - a technology to run native code in the browser in a secure manner.
> As you will see from the samples you can run fairly demanding
> computations through NaCl. I am sure it can be integrated with GWT.
> Other alternatives to run native code:
>
> - A browser plugin (this is probably a lot of work)
> - Java Applet (not sure if you can attach a DLL to an applet, but at
> least you can run Java code natively)
>
> Yegor
>
> On Nov 5, 7:40 am, Darin <[email protected]> wrote:
>
> > Hi, guys.
>
> > So here is what I've "accomplished" thus far. I've loaded the
> > DynaTable sample app directly from the GWT website. I've tested that
> > this app works in (a) hosted mode, (b) compiled from hosted mode, and
> > (c) actually deployed on the Tomcat server. So far, so good. I then
> > added the following class:
>
> > package com.google.gwt.sample.dynatable.server;
>
> > public class NativeCodeClass {
> >         static {
> >                 System.load("C:\\Documents and Settings\\Darin\\My 
> > Documents\\eclipse
> > \\workspace\\DynaTable\\war\\SolverLibrary.dll");
> >         }
> >         public native String validatePassword(String username, String
> > password);
>
> > }
>
> > and added a single line to SchoolCalendarServiceImpl.java (which is
> > definitely server code):
>
> > private static NativeCodeClass nativeCode=new NativeCodeClass();
>
> > I promise that the SolverLibrary is in the location I specified.
> > (Because I'm using the load function rather than the loadLibrary, in
> > theory it shouldn't matter where the java.library.path is pointing
> > to.) I also promise that there is a function in SolverLibrary called
> > validatePassword with that signature. Though the entire program
> > doesn't crash (kudos to the GWT programmers), the RPC call fails to
> > execute and retrieve the table. I am now convinced that the problem is
> > pretty much entirely due to the fact that the server side code is
> > having trouble interacting with native code (i.e. loading a simple
> > DLL). I have looked up this procedure via JNI (and have tried the
> > LoadLibrary version of the system call as well) and it appears as if
> > I'm doing everything correctly. Do any of you know if there exists a
> > sample application that loads a native code DLL that I can test on my
> > machine? Thanks for all your suggestions thus far.
>
> > Best, Darin
>
> > On Nov 5, 6:27 am, jhulford <[email protected]> wrote:
>
> > > Make sure you're wrapping the library path in quotes too - otherwise
> > > you just set the path to C:\Program.  You also probably don't want to
> > > completely replace the library path with you own because there's some
> > > optimized bits of Tomcat that use jni.  Google 'jni tomcat' and you'll
> > > get lots of information about how to go about doing this...here's a
> > > good 
> > > starter:http://wiki.apache.org/tomcat/HowTo#I.27m_encountering_classloader_pr....
>
> > > I'd also do like what Jeff said...get a version of your web app
> > > running sans the native stuff and work forward from there since it
> > > sounds like you might have other issues besides just the jni loading.
>
> > > On Nov 4, 4:43 pm, Darin <[email protected]> wrote:
>
> > > > Hello again, everyone.
>
> > > > Tomcat is now installed and running. Unfortunately, I am getting
> > > > exactly the same behavior as before. The code to process the returned
> > > > value on the client is as follows:
> > > >         securityService.validatePassword(message, new
> > > > AsyncCallback<CompressedMessage>(){
> > > >                         @Override
> > > >                         public void onFailure(Throwable caught) {
> > > >                                 displayErrorBox("Server error","Unable 
> > > > to contact the server.");
> > > > return;
> > > >                         }
> > > >                         @Override
> > > >                         public void onSuccess(CompressedMessage result) 
> > > > {
> > > >                                 String 
> > > > replyString=compression.Decompress(result);
> > > > and so on...
>
> > > > I am getting the top error box every time: "Unable to contact the
> > > > server".Technically, Tomcat is not throwing an error; it just can't
> > > > seem to process the RPC. This is the same behavior that it was
> > > > exhibiting before when I was using the C version of the Apache server.
> > > > With respect to jhulford's suggestion: I changed the java.library.path
> > > > in Tomcat using the command
> > > > -Djava.library.path=C:\Program Files\Apache Software Foundation\Tomcat
> > > > 6.0\webapps\ROOT
> > > > Then I stopped and restarted the Tomcat service and got exactly the
> > > > same behavior. (That was depressing because I really thought that was
> > > > going to work.) And I'm out of ideas again... Anything else I should
> > > > try?
>
> > > > Best, Darin
>
> > > > On Nov 4, 1:17 pm, Darin <[email protected]> wrote:
>
> > > > > Hi, guys. Thanks again everyone for your help. (Sorry if the thanking
> > > > > gets repetitive, but I've seen so many impatient and ungrateful
> > > > > nimrods on forum pages like these that I'd prefer to be overly polite
> > > > > than seem unappreciative.)
>
> > > > > From your responses, I believe that I may have a solution to the
> > > > > problem. The Apache server that I downloaded was the C version of the
> > > > > server which, it appears, does not support Java at all. When I
> > > > > download and install Tomcat, hopefully one issue will go away.
> > > > > However, there is the other issue that the Java is calling native code
> > > > > from a directory that the Java environment will not be aware of. This
> > > > > may be slightly harder to remedy, but if I understand "jhulford"
> > > > > correctly, it is possible to determine what the java.library.path is
> > > > > and place the C/C++ dll there. I will research this and get back to
> > > > > everyone with the results.
>
> > > > > Best, Darin
>
> > > > > On Nov 4, 6:39 am, Jeff Chimene <[email protected]> wrote:
>
> > > > > > On Wed, Nov 4, 2009 at 7:03 AM, Darin <[email protected]> wrote:
>
> > > > > > > Hi, Adrian and Jeff.
>
> > > > > > > Thanks again for the help from both of you. I greatly appreciate 
> > > > > > > it.
>
> > > > > > No prob.
>
> > > > > > I'm still looking for two answers:
> > > > > > 1. What error are you getting when running using Apache?
> > > > > > 2. What  Java server are you using outside development mode? Apache 
> > > > > > doesn't
> > > > > > support Java. When in development mode, you're using Tomcat. Even 
> > > > > > when
> > > > > > compiling and running, you're still (probably) using Tomcat (unless 
> > > > > > you're
> > > > > > using -noserver, and it doesn't sound like you are).
>
> > > > > > > I have two files in the server. One of them is 
> > > > > > > SecurityServiceImpl and
> > > > > > > the code looks like this (skipping the includes, etc.):
> > > > > > > public class SecurityServiceImpl extends RemoteServiceServlet
> > > > > > > implements SecurityService {
> > > > > > >        private static NativeCodeClass nativeCode=new 
> > > > > > > NativeCodeClass();
> > > > > > >        private CompressClass compression=new CompressClass();
> > > > > > >       �...@override
> > > > > > >        public CompressedMessage 
> > > > > > > validatePassword(CompressedMessage m) {
> > > > > > >                String message=compression.Decompress(m);
> > > > > > >                String 
> > > > > > > username=message.substring(0,message.indexOf(','));
> > > > > > >                String 
> > > > > > > password=message.substring(message.indexOf(',')
> > > > > > > +1,message.length());
> > > > > > >                String 
> > > > > > > returnString=nativeCode.validatePassword(username,
> > > > > > > password);
> > > > > > >                CompressedMessage
> > > > > > > replyMessage=compression.Compress(returnString);
> > > > > > >                return replyMessage;
> > > > > > >        }
> > > > > > > }
> > > > > > > The other file is called NativeCodeClass and the code looks like 
> > > > > > > this:
> > > > > > > public class NativeCodeClass {
> > > > > > >        static {
> > > > > > >                System.loadLibrary("SolverLibrary");
> > > > > > >        }
> > > > > > >        public native String validatePassword(String username, 
> > > > > > > String
> > > > > > > password);
> > > > > > > }
>
> > > > > > > I have doublechecked that both of these files are definitely in 
> > > > > > > the
> > > > > > > server code (and these are the only files in the server code). 
> > > > > > > When I
> > > > > > > run the code from within hosted mode, this code works (i.e. finds 
> > > > > > > the
> > > > > > > SolverLibrary and checks the entered password, etc.). And (here 
> > > > > > > comes
> > > > > > > the important part), when I compile it and run it from within the
> > > > > > > browser by pressing the Compile/Browse button from inside hosted 
> > > > > > > mode,
> > > > > > > it works just fine as well inside Mozilla. It fails when I copy 
> > > > > > > the
> > > > > > > directories to another place on the hard drive. Unless I am 
> > > > > > > seriously
> > > > > > > confused (and I have to admit that this is a possibility), if the
> > > > > > > problem was one where the native code was executing inside of
> > > > > > > Javascript, it could not run correctly from inside the browser 
> > > > > > > after
> > > > > > > the Compile/Browse step.
>
> > > > > > > It occurs to me that maybe my RPC calls to the server are not
> > > > > > > functioning correctly when I try to move the folders to somewhere 
> > > > > > > else
> > > > > > > on the hard drive. Is there an obvious reason why that might 
> > > > > > > happen?
> > > > > > > Thanks for all your help.
>
> > > > > > > Darin
>
> > > > > > > On Nov 4, 1:56 am, Adrian <[email protected]> wrote:
> > > > > > > > Hi guys,
>
> > > > > > > > I think Darin might not be up to speed with the differences 
> > > > > > > > between
> > > > > > > > server side and client side stuff and also how web environment 
> > > > > > > > differs
> > > > > > > > from the desktop environment. You might know this already but 
> > > > > > > > if not
> > > > > > > > it might clear a few things up.
>
> ...
>
> read more »
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to