dynarithmic / twain_library

Dynarithmic TWAIN Library, Version 5.x
Apache License 2.0
56 stars 24 forks source link

Scanning in JDK17 #67

Closed johandevarwaere closed 1 year ago

johandevarwaere commented 1 year ago

We've currently integrated an Avision IDA6 photo scanner into an Oracle Java 8 32 bit application. We're are going to migrate to Oracle JDK17 64 bit.

We start the scan like this: DTwainAcquisitionArray acquireResult = twainApi.DTWAIN_AcquireNative(twainSourceId, DTwainPixelType.PIXELTYPE_DEFAULT, 1, false, true); In the java 8 32 bit application the scan starts immediately. Launching the same application in java 8 64 bit (with corresponding dlls loaded) works fine as well. But when I launch with Oracle JDK 17 64 bit, nothing happens. 'acquireResult.getNumAcquisitions()' returns 0 But I cant see an error/exception being thrown. Do you have any idea what might cause this behaviour?

Kind regards, Johan

dynarithmic commented 1 year ago

I would highly suggest migrating to the latest Java interface to DTWAIN and attempting the demo programs there.

If the simplest demo doesn't work with Oracle JDK17, then I will take a look further.

dynarithmic commented 1 year ago

I quickly downloaded the Oracle JDK 17, and ran the demo program com.dtwain.demos.SetJNIVersionDemo.java.

1) I am using Eclipse to run the program. 2) I made sure that I am using the jdk-17 JRE. 3) The demo program starts by prompting you which JNI version to use. Choose '4' (64-bit Unicode). 4) If everything is working correctly, you should get a response in the console the DTWAIN DLL that is in use, the path where the DLL is found, and the JNI version in use.

I modified the demo slightly by allowing a selection of a TWAIN Source. After building and running the modified program, I had no issues selecting the TWAIN Working Group sample data source using jdk-17.

Here is the full program:

import java.util.Scanner;
import com.dynarithmic.twain.DTwainGlobalOptions;
import com.dynarithmic.twain.highlevel.TwainSession;
import com.dynarithmic.twain.highlevel.TwainSource;

public class SetJNIVersionDemo
{
    // Simple acquire to a file
    public void run() throws Exception
    {
        System.out.println("Please choose the JNI to use for your application:\n");
        System.out.println("  1. 32-bit ANSI");
        System.out.println("  2. 32-bit Unicode");
        System.out.println("  3. 64-bit ANSI");
        System.out.println("  4. 64-bit Unicode");
        System.out.println("  5. 32-bit ANSI Debug");
        System.out.println("  6. 32-bit Unicode Debug");
        System.out.println("  7. 64-bit ANSI Debug");
        System.out.println("  8. 64-bit Unicode Debug");
        System.out.print("(1 - 8): ");

        @SuppressWarnings("resource")
        Scanner input = new Scanner(System.in);
        int jniToUse = input.nextInt();
        if ( jniToUse < 1 || jniToUse > 8)
            System.out.println("Invalid choice");
        else
        {
            // Set the JNI version
            DTwainGlobalOptions.setJNIVersion(jniToUse - 1);

            // Start a TWAIN session
            TwainSession twainSession = new TwainSession();

            // Verify these are the DLLs being used
            System.out.println("The DTWAIN DLL in use: " + twainSession.getDTwainPath());
            System.out.println("The JNI Version: " + DTwainGlobalOptions.getJNIVersionAsString());

            TwainSource source = twainSession.selectSource();
            if ( source.isOpened())
                System.out.println("The name of the source is " + source.getInfo().getProductName());
            // Close down the TWAIN Session
            twainSession.stop();
        }
    }

    public static void main(String [] args)
    {
        SetJNIVersionDemo s = new SetJNIVersionDemo();
        try
        {
            s.run();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The console should look something like this when running the program and if you select your scanner in the TWAIN dialog:

Please choose the JNI to use for your application:

  1. 32-bit ANSI
  2. 32-bit Unicode
  3. 64-bit ANSI
  4. 64-bit Unicode
  5. 32-bit ANSI Debug
  6. 32-bit Unicode Debug
  7. 64-bit ANSI Debug
  8. 64-bit Unicode Debug
(1 - 8): 4
The DTWAIN DLL in use: c:\dtwain_bin\DTWAIN64U.dll
The JNI Version: JNI_64U
The name of the source is <name of the scanner>
johandevarwaere commented 1 year ago

Thanks for your quick reply.

I've tried your example, but I run into an error: Exception in thread "main" java.lang.NoSuchMethodError: static com/dynarithmic/twain/highlevel/TwainCallback;.onTwainEvent(IJ)I

I've followed the guidelines (https://github.com/dynarithmic/twain_library-java). The dtwain (5.3.0.7) and dtwainjni dlls are in the root of the project, and all necessary jar files are included as well.

I've got jdk 17.0.6 installed.

dynarithmic commented 1 year ago

The issue is that the dtwainjni.info file required an update, which is available here.

Replace the existing one with the one in the link.

dynarithmic commented 1 year ago

I also updated master with the latest version.

Basically it was an issue with the signature change of OnTwainEvent differing in versions before the initial release. That should be resolved now.

johandevarwaere commented 1 year ago

It solves the error, I'm able to scan now.

Thank you very much.

dynarithmic commented 1 year ago

That's good to hear.

Just to let you know, the demo program SimpleImageNativeAcquireDemo.java has an example of getting the number of acquired images, similar to what you are attempting to do.

I will close the ticket.