Search code examples
javaspring-mvcocrtesseracttess4j

Tesseract invalid memory access when i am using tess4j1.3.0


When using OCR tess4j using rest controller getting exception "java.lang.Error: Invalid memory access". Have also set the data path but as soon as i run the program it throws the above mentioned exception. And i have added the -Djava.jna.path with the libtesseract 302 dll. As withouth specifying the jna path i was getting "UnsatisfiedLinkError".

My Rest Controller Code

 private Logger LOGGER = LoggerFactory.getLogger(Tess4jV1.class);

        @Autowired
        private ImageRepository repository;

        @RequestMapping(value = "ocr/ping", method = RequestMethod.GET)
        public Status ping() throws Exception {
            return new Status("OK");
        }

        @RequestMapping(value = "ocr/v0.9/upload", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
        public Status doOcrFile(@RequestBody final Image image) throws Exception {
            // File tmpFile = File.createTempFile("ocr_image",
            // image.getExtension());
            String uplodPath = "";
            String selectedDocument = "";

            String OriginalFilename = "ocr_image";

            byte[] bytes = image.getImage();

            uplodPath = System.getProperty("java.io.tmpdir");
            uplodPath = uplodPath.replace("\\", "/");
            if (!uplodPath.endsWith("/"))
                uplodPath = uplodPath + "/";
            uplodPath = uplodPath + "OCR_DMSIMGS";
            File fath = new File(uplodPath);
            if (!fath.exists())
                fath.mkdirs();
            String fileNme = "";
            String recogniseStr = "";
            try {
                fileNme = System.nanoTime() + OriginalFilename;
                uplodPath = uplodPath + "/" + fileNme + image.getExtension();
                FileOutputStream dfos = new FileOutputStream(uplodPath);
                dfos.write(bytes);
                dfos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.err.println(fath.getAbsolutePath());
            //
            // System.err.println(tmpFile.getAbsolutePath());
            try {
                // FileUtils.writeByteArrayToFile(tmpFile,
                // Base64.decodeBase64(image.getImage()));
                Tesseract tesseract = Tesseract.getInstance(); // JNA Interface
                                                                // Mapping
                tesseract.setDatapath("C://Users//58181.INFOTECH//Downloads//Tess4J-1.3-src//Tess4J//tessdata");
                ImageIO.scanForPlugins();
                String imageText = tesseract.doOCR(new File(uplodPath));
                LOGGER.debug("OCR Image Text = " + imageText);
            } catch (Exception e) {
                LOGGER.error("Exception while converting/uploading image: ", e);
                throw new TesseractException();
            } /*
                 * finally { tmpFile.delete(); }
                 */
            return new Status("success");
        }

        @RequestMapping(value = "ocr/v1/upload", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
        public Status doOcr(@RequestBody Image image) throws Exception {
            try {
                // FileUtils.writeByteArrayToFile(tmpFile,
                // Base64.decodeBase64(image.getImage()));
                ByteArrayInputStream bis = new ByteArrayInputStream(Base64.decodeBase64(image.getImage()));
                Tesseract tesseract = Tesseract.getInstance(); // JNA Interface
                                                                // Mapping
                String imageText = tesseract.doOCR(ImageIO.read(bis));
                image.setText(imageText);
                repository.save(image);
                LOGGER.debug("OCR Result = " + imageText);
            } catch (Exception e) {
                LOGGER.error("TessearctException while converting/uploading image: ", e);
                throw new TesseractException();
            }

            return new Status("success");
        }

        @RequestMapping(value = "ocr/v1/images/users/{userId}", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
        public List<Image> getUserImages(@PathVariable String userId) throws Exception {
            List<Image> userImages = new ArrayList<>();
            try {
                userImages = repository.findByUserId(userId);
            } catch (Exception e) {
                LOGGER.error("Exception occurred finding image for userId: {} ", userId, e);
                throw new Exception();
            }
            return userImages;
        }

Exception:

Adding paths from jna.library.path: C:\Users\58181.INFOTECH\Downloads\Tess4J-1.3-src\Tess4J\lib\win32-x86-64
Trying C:\Users\58181.INFOTECH\Downloads\Tess4J-1.3-src\Tess4J\lib\win32-x86-64\libtesseract302.dll
Found library 'libtesseract302' at C:\Users\58181.INFOTECH\Downloads\Tess4J-1.3-src\Tess4J\lib\win32-x86-64\libtesseract302.dll
9226 [http-nio-8080-exec-2] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.Error: Invalid memory access] with root cause 
java.lang.Error: Invalid memory access
    at net.sourceforge.tess4j.TessAPI1.TessBaseAPIInit2(Native Method)
    at net.sourceforge.tess4j.Tesseract1.init(Tesseract1.java:274)
    at net.sourceforge.tess4j.Tesseract1.doOCR(Tesseract1.java:209)
    at net.sourceforge.tess4j.Tesseract1.doOCR(Tesseract1.java:158)
    at net.sourceforge.tess4j.Tesseract1.doOCR(Tesseract1.java:142)
    at com.tess4j.rest.OcrRestController.doOcrFile(OcrRestController.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

Solution

  • Invalid memory access for Tess4J usually means incorrect datapath, which should be set to the parent folder of tessdata folder, such as:

    tesseract.setDatapath("C:/Users/58181.INFOTECH/Downloads/Tess4J-1.3-src/Tess4J/");

    Note the double slashes should be double backslashes or single slashes.