Skip to main content
For Linux, See the Developer’s Help of the Linux distribution for the full list. One notable limitation is that objects implementing IEngineLoader are not available on Linux or macOS (See Differences between ABBYY FineReader Engine 12 for Windows and Linux).

Adding FineReader Engine library to a Java project

ABBYY FineReader Engine includes a com.abbyy.FREngine-%BUILD_ID%.jar file, which contains the Java class library for FineReader Engine. You can find it in the Inc/Java folder. The path to this file can be specified in the classpath parameter in the command line and in project settings in different Java development environments. Example:
$JDK/bin/javac -classpath <path>/com.abbyy.FREngine-%BUILD_ID%.jar Hello.java
$JDK is the path to Java Development Kit.
See the list of supported Java Development Kits in System Requirements.

Loading and unloading FineReader Engine

You can use the static Engine class to load the Engine object. The Engine class provides methods that correspond to the ABBYY FineReader Engine functions for loading and unloading the Engine:
FunctionEngine class methodThe signature of the Engine class method
InitializeEngineInitializeEnginecsharp static public IEngine InitializeEngine( String dllFolder, String customerProjectId, String licensePath, String licensePassword, String dataFolder, String tempFolder, boolean isSharedCPUCoresMode ) throws Exception;
DeinitializeEngineDeinitializeEnginestatic public void DeinitializeEngine() throws Exception;
import com.abbyy.FREngine.*;
public class Hello {
    public static void main( String[] args )
    {
        try {
            // Load the Engine with Online License
            engine = Engine.InitializeEngine( path, customerProjectId, LicensePath, LicensePassword, "", "", false );
            try {
                // Load a predefined profile
                engine.LoadPredefinedProfile( "DocumentConversion_Accuracy" );
                // Process images
                IFRDocument document = engine.CreateFRDocument();
                ...
            } finally {
                engine = null;
                System.runFinalization();
                Engine.DeinitializeEngine();
            }
        } catch( Exception ex ) {
            trace( ex.getMessage() );
        }
    }
    private IEngine engine = null;
...
}
The com.abbyy.FREngine-%BUILD_ID%.jar file is a self-unpacking archive which is unpacked on your machine the first time you use FineReader Engine Java API. The default folder where the contents are unpacked is Inc/Java . If you need to use another folder, call the Engine.SetJNIDllFolder method before loading the Engine by any of the methods described above. To find out which folder is currently set for unpacking the archive, call the Engine.GetJNIDllFolder .

Handling errors

ABBYY FineReader Engine can throw the exceptions of the following types:
  • java.lang.OutOfMemoryError
  • com.abbyy.FREngine.EngineException
The com.abbyy.FREngine.EngineException exception inherits from the java.lang.Exception and contains one additional method int getHResult, which returns the HRESULT code of the error that occurred. For an exception of this type, you can not only retrieve the error message using the getMessage() method but also retrieve the error code.
try {
    ...
} catch( Exception ex ) {
    displayMessage( "Message = " + ex.getMessage() );
    if( ex instanceof EngineException ) {
        displayMessage( "HResult = " + Integer.toString( ( ( EngineException )ex ).getHResult() ) );
    }
}

Calling methods with out-parameters

There are several methods in ABBYY FineReader Engine API which have out-parameters that receive a new value after the method call and must be passed by reference. These parameters are marked in the type library and in descriptions of methods in this Developer’s Help as [out] or [in, out]. When working with ABBYY FineReader Engine in Java, you have to use a special Ref class to pass a parameter by reference. See examples below. Example in which the out-parameters are passed by reference to the IFRPage::FindPageSplitPosition method:
Ref<PageSplitDirectionEnum> _ps = new Ref<PageSplitDirectionEnum>();
Ref<Integer> _start = new Ref<Integer>();
Ref<Integer> _end = new Ref<Integer>();
page.FindPageSplitPosition( null, null, _ps, _start, _end );
PageSplitDirectionEnum ps = _ps.get();
Integer start = _start.get();
Integer end = _end.get();
Example in which the in/out parameters are passed by reference to the ICoordinatesConverter::ConvertCoordinates method:
Ref<Integer> _x = new Ref<Integer>( 100 );
Ref<Integer> _y = new Ref<Integer>( 200 );
cnv.ConvertCoordinates( ImageTypeEnum.IT_Modified, ImageTypeEnum.IT_Base, _x, _y );
Integer x = _x.get();
Integer y = _y.get();

Collecting garbage

FineReader Engine supports working with the AutoCloseable interface, which allows you to use the try statement to access the resources allocated for objects. It means that once the try block reaches the end, all allocated resources will be closed automatically, without explicitly calling closure methods. We recommend that you use the try statement for all objects in your code (see the example below):
try( IFRDocument document = engine.CreateDocument() )
 {
  // Add image to a document
  document.AddImageFile( imagePath, null, null );
  ...
  // Save results to PDF
  document.Export( pdfExportPath, FileExportFormatEnum.FEF_PDF, pdfParams );
 }

Working with enumerations

Methods and properties which accept a combination of enumeration constants require the int value to be passed to the method/property. To obtain the int value of an enumeration constant, use the getValue method which is supported by all enumerations. Here is sample code showing how to set the BwPictureFormats property of the PDFPictureCompressionParams object:
IPDFExportParams pep = engine.CreatePDFExportParams();
IPDFPictureCompressionParams ppcp = pep.getPictureCompressionParams();
ppcp.setBwPictureFormats(BwPictureFormatsEnum.BWPF_Auto.getValue());

Using the RMI-capable wrapper

There is a separate Java wrapper version that supports remote method invocation (RMI). All classes inherit from UnicastRemoteObject and support the Remote interface; all methods may throw RemoteException. The RMI-capable wrapper uses redirecting of the PDF-processing calls to a separate thread with the initialized PDFium by default.
The RMI-capable wrapper requires Java Development Kit. See the list of supported Java Development Kits in System Requirements.
The com.abbyy.rmi.FREngine package contains the remote interfaces used by the client application; the com.abbyy.rmi.server.FREngine package is used on the server-side. Due to the limitations of method overloading, you will also need to use another dynamic library libFREngine.rmi_server.so instead of libFREngine.so. These packages are enough for a simple client-server application. However, FineReader Engine is not thread-safe in itself and therefore requires additional effort on the programmer’s part to make sure that any one Engine instance is accessed only by one worker thread at a time. See the code samples provided with the distribution package for a complete reusable implementation of the server-side pool of Engines and a multi-threaded client connecting to it (rmiPoolServer and threadPoolClient samples, com.abbyy.rmi.pool.FREngine and com.abbyy.rmi.pool.impl.FREngine packages).

Using events and callback interfaces

Note that the client-implemented events and callback interfaces should be removed from the RMI runtime after use:
java.rmi.server.UnicastRemoteObject.unexportObject( callback, true );
callback = null;