Search code examples
pythonjasper-reports

How to resolve this: pyreportjasper: ImportError: DLL load failed while importing jpy: The specified module could not be found


I want to use Jasper Reports with a python-flask app.

I have followed the installation instructions on this page: https://pypi.org/project/pyreportjasper/

It fails on the line import jpy, I am getting the error:

ImportError: DLL load failed while importing jpy: The specified module could not be found.

I am using 32 bit python Python: 3.8.6rc1. 32 bit JDK: javac 1.8.0_261

When I run pip install pyreportjasper, it says: Requirement already satisfied: jpy in c:\users....

Any ideas?


Solution

  • It seems that you need to import jpyutil and then initialize the JVM prior to calling import jpy. The following fixed this error for me. One step closer.

    import jpyutil
    jpyutil.init_jvm(jvm_maxmem='512M')
    import jpy
    

    UPDATE: so while the above statement is true, it doesn't directly address the issue of running the example code at the project page: https://pypi.org/project/pyreportjasper/

    As I dug into the code I found that jasperpy.py is attempting to import jpy BEFORE the __init__ method is run and therefore BEFORE the JVM is initialized via the jpyutil.init_jvm() method call. So I edited jasperpy.py and moved import jpy from line 14 to line 56, directly after the call to jpyutil.init_jvm() and before the call to jpy.get_type('java.io.File') and I am able to successfully run Jasper reports from python via the example code shown. Here is what my jasperpy.py looks like now.

    # -*- coding: utf-8 -*-
    # GNU GENERAL PUBLIC LICENSE
    #
    # Copyright (c) 2020 Jadson Bonfim Ribeiro <[email protected]>
    #
    
    import os
    import subprocess
    import re
    import xml.etree.ElementTree as ET
    
    import tempfile
    import jpyutil
    #import jpy
    import json
    from requests import Request, Session
    
    FORMATS = (
        'pdf',
        'rtf',
        'xls',
        'xlsx',
        'docx',
        'odt',
        'ods',
        'pptx',
        'csv',
        'html',
        'xhtml',
        'xml',
        'jrprint',
    )
    
    EXECUTABLE = 'jasperstarter'
    
    class JasperPy:
    
        _FORMATS_JSON = ('pdf')
    
        _FORMATS_METHODS_REQUEST = ('GET', 'POST', 'PUT')
    
        def __init__(self, resource_dir=False, jvm_maxmem='512M', jvm_classpath=None):
            self.WINDOWS = True if os.name == 'nt' else False
            self.SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
            self.LIBS = os.path.join(self.SCRIPT_DIR, 'jasperstarter', 'lib')
            if not os.path.isdir(self.LIBS):
                raise NameError('Unable to find lib in {0}'.format(self.LIBS))
            self.CLASSPATH = os.path.join(self.LIBS, 'jasperstarter.jar')
            if not os.path.exists(self.CLASSPATH):
                raise NameError('Unable to find jasperstarter in {0}'.format(self.LIBS))
            if jvm_classpath is None:
                jpyutil.init_jvm(jvm_maxmem=jvm_maxmem, jvm_classpath=[self.CLASSPATH])
            else:
                jpyutil.init_jvm(jvm_maxmem=jvm_maxmem, jvm_classpath=[self.CLASSPATH, jvm_classpath])
            # IMPORT jpy HERE AFTER init_jvm
            import jpy
            self.jvFile = jpy.get_type('java.io.File')
            self.jvArrays = jpy.get_type('java.util.Arrays')
            self.jvReport = jpy.get_type('de.cenote.jasperstarter.Report')
            self.jvConfig = jpy.get_type('de.cenote.jasperstarter.Config')
            self.jvDsType = jpy.get_type('de.cenote.jasperstarter.types.DsType')
            self.jvApplicationClasspath = jpy.get_type('de.cenote.tools.classpath.ApplicationClasspath')
            self.jvHashMap = jpy.get_type('java.util.HashMap')
            self.jvLocale = jpy.get_type('java.util.Locale')
            self.jvJasperFillManager = jpy.get_type('net.sf.jasperreports.engine.JasperFillManager')
            self.jvDb = jpy.get_type('de.cenote.jasperstarter.Db')
            self.jvJsonQueryExecuterFactory = jpy.get_type('net.sf.jasperreports.engine.query.JsonQueryExecuterFactory')
            self.jvJasperExportManager = jpy.get_type('net.sf.jasperreports.engine.JasperExportManager')
    .
    .
    .
    .
    

    This file is located in your Python directory under Lib\site-packages\pyreportjasper-2.0.2-py3.8.egg\pyreportjasper. While this is currently a hack to make it work, there obviously needs to be a fix to the package which I will attempt to address on the pyreportjasper github page.