dynarithmic / twain_library

Dynarithmic TWAIN Library, Version 5.x
Apache License 2.0
60 stars 25 forks source link

Slow response to Java application from Fujitsu Driver #24

Open MichaelHurd opened 2 years ago

MichaelHurd commented 2 years ago

I frequently get very slow results when trying to use a Fujitsu scanner from the java application. This happens both in my Java app and the sample Java DTwainDemoFrame. When debugging, it seems to happen precisely when calling the function m_api.DTWAIN_AcquireNative or m_api.DTWAIN_AcquireBuffered.

One thing I find odd, but may help diagnose the issue, is that while it's in this stuck state, the scanner instantly unsticks and starts scanning if I either lock my screen or hit Ctrl + Alt + Delete. Something about switching the Windows user mode seems to free up whatever is locking it. Also, when using the demo application, it never seems to happen the first time I attempt a scan, only on the second and later attempts. Perhaps something about the previous connection isn't closing properly?

The scanner driver I am using can be found here: https://imagescanner.fujitsu.com/global/dl/setup/psip-twain64-302.html

Sorry for giving you such a tricky issue on December 23rd. Merry Christmas!

dynarithmic commented 2 years ago

The Fujitsu scanner drivers can at times do strange things, such as lock the entire TWAIN session for any scanner to respond (Fujitsu or non-Fujitsu). I have found that nothing short of a reboot or closing down all the Fujitsu services seems to make the scanners responsive. Your situation does not surprise me concerning a Fujitsu scanner driver.

1) Does the scanner work for the DTWDEMO.exe or any other of the demo programs? If so, the library itself is ok and possibly something in Java or JVM is causing the issue.

2) What version of the JVM are you using? 8.0, 11, etc.

3) The actual Fujitsu scanner model?

The Java framework is being redone, with numerous changes both in the JNI layer and in the Java code. Thus the current version you are using will be obsolete as soon as the updated version is posted. However, this will still take a few weeks before this happens.

MichaelHurd commented 2 years ago

It does consistently work for the DTWDEMO programs. I'm using Amazon Corretto 8.0.302 (64-bit) I'm using an fi-7160 model.

I haven't heard about the JNI framework being redone. Do you know which version of Java the new framework will be released in? We may be able to hold out until then.

Thanks for such a fast response!

dynarithmic commented 2 years ago

Have you tried acquiring to a file, i.e. DTWAIN_AcquireFile? If that doesn't cause an issue, it could have something to do with the memory having to be allocated for the image(s) when issuing calls to DTWAIN_AcquireNative and DTWAIN_AcquireBuffered and the Java/JVM possibly not handling the memory correctly.

If DTWAIN_AcquireFile works, maybe a workaround for you is to save the image to a file (BMP), and have separate Java code that processes the file, with that code being independent of DTWAIN.

The new framework is based on Java 1.8.

MichaelHurd commented 2 years ago

Unfortunately, it still has a tendency to freeze, even when acquiring to a file. It was worth a shot, though!

I misunderstood you earlier, I thought you meant Java itself was changing to improve upon JNI, but you meant the Java Framework for this library. That's good; it means we won't have to change out our Java version. :) I'll will keep my fingers crossed hoping the upgrade eliminates this bug!

dynarithmic commented 2 years ago

Can you test with another device (non-Fujitsu)?

Also, have you tried a simple console Java application, and not a GUI one?

MichaelHurd commented 2 years ago

Yes, the library works perfectly with our test Canon devices. Fujitsu is very common, though, so we don't want to tell people to buy different devices or lock their computers just to scan.

I haven't tried a console Java application. Since our application is client-facing, we require a GUI.

dynarithmic commented 2 years ago

The reason why you should test a console application is to rule out whether this is an AWT/Swing issue, since the GUI runs on a different thread. If the console application works without issues, then the issue points to threading and the GUI.

It also whittles down the program to the bare minimum, which is what should be done when diagnosing these issues.

MichaelHurd commented 2 years ago

I did get a small console app running, and unfortunately it still freezes when scanning.

dynarithmic commented 2 years ago

I suggest you call DTWAIN_SetTwainLog, log to a file, and see where the application is frozen. Or better yet, if you have Visual Studio, attach to the running Java process for your application from the Debug menu and choose "Break All". Inspect the call stack to see what is idling the application.

Since the problem does not occur in the DTWDEMO program, the only conclusion is that Java, the JVM, or something Java related is interfering with the operation of the scanner.

dynarithmic commented 2 years ago

As to logs, having the available logs is basically a prerequisite in diagnosing any TWAIN issues. The DTWAIN_SetTwainLog allows the logging of all the calls made between DTWAIN and the underlying TWAIN subsystem.

Also, you didn't mention what are the parameters being used with respect to the images being acquired. Are these high-resolution scans, where the amount of memory for each image is relatively very high?

But again, all of these questions are answered if logs are produced, since all of that information will be available. As to the DTWAIN_SetTwainLog, use DTWAIN_LOG_ALL and give a file name. The other alternative is to add a DTwainLogger instance from Java, enable it, and inspect the messages that will show up in the Java console. The Java full demo program has an option to log messages, so maybe you can use that.

MichaelHurd commented 2 years ago

It's a pretty small image. When the program does work, it scans very quickly. I configured the log messages, and it looks like it's freezing between these two lines:

[2022-01-07 08:50:35] <<<===Exiting dynarithmic::LLAcquireImage returning value of 0 [2022-01-07 08:55:16] ===>>>Entering DTWAIN_IsTwainMsg(pMsg=000000F4243FA6C8)

It definitely feels like something Java-related, but yeah, it's tricky to figure out exactly what it is.

dynarithmic commented 2 years ago

Are you acquiring images without the scanner user interface? If so, try acquiring with the UI enabled.

Unfortunately, I do not have a fi-7160 or any Fujitsu scanner that is of a similar model, so I can't really help to diagnose this to a great extent except to take guesses as to what the problem is or what you can try.

The logs that are produced tell which functions are being called, and the one you have, DTWAIN_IsTwainMessage, is sent in a message loop to the device, as per TWAIN spec. If the message loop is stuck there, I think that it really is stuck in the TWAIN Data Source Manager somewhere.

You can try to use the 2.0 version of the TWAIN DSM (TWAINDSM.DLL). You can adjust the Java code to call DTWAIN_SetTwainDSM(2) right after DTWAIN_LoadLibrary() and see if that helps (you should find it in DTwainJavaAPI.java). Make sure that TWAINDSM.DLL is located in the same directory as the DTWAIN DLL, or on your system path.

Also I would concentrate on the file acquire, as the native acquire for the Java interface goes through more hurdles to ensure the memory populates the various Java objects on the C++ side. The file acquire is a lot more simpler, since no Java-side objects need to be created.

Since all the source code is available, you may be able to debug it, but you would need to have Visual Studio, and a somewhat advanced knowledge of C++ and TWAIN. An easier thing to do, assuming you have Visual Studio, is when the program gets stuck, attach to the Java process that is running your app from Visual Studio.

The way you do this is in Visual Studio, go to the Debug menu item from the main menu, choose "Attach" and then choose the java process that's running your app. Then when the attachment is complete, go to the debug menu and try "Break All". You will then get the real call stack of where things are, and then you get a definitive indication of where things are stuck.

MichaelHurd commented 2 years ago

Unfortunately, it pauses in the exact same place with or without using the UI, even if I'm scanning to a file instead of native. I'm using the 64-bit version of the drivers, so if I'm reading the help files correctly, I'm already using the TWAINDSM.DLL.

I'll try attaching to the Java process from Visual Studio to find out precisely where this is getting stuck.

dynarithmic commented 2 years ago

OK, If it's the 64-bit version of the Data Source Manager, that is open source from the Twain Working Group. It's been a while since I've had to compile it, but you can get it here:

https://github.com/twain/twain-dsm/tree/master/TWAIN_DSM

It is probably newer than the version you're using, so a remote possibility is that this could fix the issue you're having. Even if it doesn't fix the issue, if you can get it to compile with debugging info (Visual Studio) and replace the one you have now, then you have all the pieces, except for the Fujitsu driver code, to debug the issue.