Using pyimagej from Spyder

I am having a similar issue: I’m trying to run imageJ (FIJI) through Spyder and get the following:

import imagej; ij = imagej.init('/Applications/Fiji.app')
Added 398 JARs to the Java classpath.
Traceback (most recent call last):

  File "<ipython-input-1-d430cd7f0157>", line 1, in <module>
    import imagej; ij = imagej.init('/Applications/Fiji.app')

  File "/Users/stuart/anaconda3/lib/python3.7/site-packages/imagej/imagej.py", line 104, in init
    import imglyb

  File "/Users/stuart/anaconda3/lib/python3.7/site-packages/imglyb/__init__.py", line 38, in <module>
    config, _ = _init_jvm_options()

  File "/Users/stuart/anaconda3/lib/python3.7/site-packages/imglyb/__init__.py", line 33, in _init_jvm_options
    import scyjava

  File "/Users/stuart/anaconda3/lib/python3.7/site-packages/scyjava/__init__.py", line 122, in <module>
    jnius = _init_jvm()

  File "/Users/stuart/anaconda3/lib/python3.7/site-packages/scyjava/__init__.py", line 64, in _init_jvm
    mvn = str(subprocess.check_output(['mvn', '-v']))

  File "/Users/stuart/anaconda3/lib/python3.7/subprocess.py", line 395, in check_output
    **kwargs).stdout

  File "/Users/stuart/anaconda3/lib/python3.7/subprocess.py", line 472, in run
    with Popen(*popenargs, **kwargs) as process:

  File "/Users/stuart/anaconda3/lib/python3.7/subprocess.py", line 775, in __init__
    restore_signals, start_new_session)

  File "/Users/stuart/anaconda3/lib/python3.7/subprocess.py", line 1522, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)

FileNotFoundError: [Errno 2] No such file or directory: 'mvn': 'mvn'

I THINK the issue is in my JAVA_HOME path (via traceback to init.py line 64) which I can’t seem to fix…

   # attempt to set JAVA_HOME if the environment variable is not set.
    JAVA_HOME_STR = 'JAVA_HOME'
    if JAVA_HOME_STR not in globals():
        JAVA_HOME = None
        try:
            _logger.debug('Checking %s environment variable', JAVA_HOME_STR)
            JAVA_HOME = os.environ[JAVA_HOME_STR]
        except KeyError:
            _logger.debug('No %s environment variable', JAVA_HOME_STR)
        if not JAVA_HOME:
            # NB: This logic handles both None and empty string cases.
            _logger.debug('%s still unknown; checking with Maven', JAVA_HOME_STR)
            # attempt to find Java by interrogating maven
            # (which we have because it is needed by jgo)
            try: 
                mvn = str(subprocess.check_output(['mvn', '-v']))
            except subprocess.CalledProcessError as e:
                _logger.error('Unable to import scyjava, could not find Maven')
                return None
            _logger.debug('Maven said: %s', mvn)
            try:
                begin = mvn.index('Java home: ')
            except ValueError as e:
                # in some versions of maven it is instead called runtime
                try:
                    begin = mvn.index('runtime: ')
                except ValueError as e:
                    _logger.error('Unable to import scyjava, could not locate jre')
                    return None
            # cut out 'Java home' or 'runtime'
            begin = mvn.index('/', begin)
            end = mvn.index('\\n', begin)
            JAVA_HOME = mvn[begin:end]
        java_path = Path(JAVA_HOME)
        if java_path.is_dir():
            _logger.debug('%s found at "%s"', JAVA_HOME_STR, JAVA_HOME)
            if java_path.name is 'jre':
                _logger.debug('JAVA_HOME points at jre folder; using parent instead')
                JAVA_HOME = str(java_path.parent)
            os.environ['JAVA_HOME'] = JAVA_HOME
        else:
            _logger.error('Unable to import scyjava: jre not found')
            return None
    else:
        _logger.debug('%s found in globals', JAVA_HOME_STR)

The exception says that you don’t have maven installed (or on the PATH):

FileNotFoundError: [Errno 2] No such file or directory: 'mvn': 'mvn'

This error means that your mvn executable is not found. One way to solve it is to put the path to mvn on your PATH. (If it were a JAVA_HOME issue, you might see an error about how the mvn execution returned a non-zero exit code, but not that the command cannot be found.)

@Stuart_Humphries How did you install pyimagej? With conda? Or purely with pip? And how are you launching Spyder? You may want to read the Spyder guide about environments if you are not already familiar with the interaction between Spyder and environment systems like conda and virtualenv.

You can also try using pyimagej from the command line to make sure your installation is good, and only then mix in Spyder, to narrow down where the problem lies.

1 Like

Thanks @ctrueden and @hanslovsky

I installed pyimagej with conda
Spyder is launched via anaconda-navigator

maven is installed (I checked via the conda list command recommended above)

I added ~/anaconda3/bin to my path as mvn sits there (checked via which mvn) , but it is a (symbolic?) link not an executable as others in the folder. Does that make a difference?

adding ~/anaconda3/opt/maven/bin does not help either

That should not make a difference. My suspicion is that the environment inside spyder is not the same as in the command line. Inside your Python code, can you print the PATH variable, e.g.

import os
print(os.environ['PATH'])

If set correctly, this should include the directory that contains the mvn executable. This is true for Linux and macOS, and possibly Windows.

1 Like

Thanks!

The path seems fine and I am in the base environment for both terminal and spyder.

After a couple of restarts the mvn error disappeared, and I was able to proceed by installing the legacy v6 of java. Now however, when I run the test script I have I get:

ij = imagej.init('/Applications/Fiji.app')
Added 398 JARs to the Java classpath.
[WARNING] 1 exceptions occurred during plugin discovery.

runfile('/Users/stuart/HoloPyGuy-master/fijitest.py', wdir='/Users/stuart/HoloPyGuy-master')
Traceback (most recent call last):

  File "<ipython-input-2-29942ca8b489>", line 1, in <module>
    runfile('/Users/stuart/HoloPyGuy-master/fijitest.py', wdir='/Users/stuart/HoloPyGuy-master')

  File "/Users/stuart/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 827, in runfile
    execfile(filename, namespace)

  File "/Users/stuart/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 110, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "/Users/stuart/HoloPyGuy-master/fijitest.py", line 2, in <module>
    ij = imagej.init('/Applications/Fiji.app')

  File "/Users/stuart/anaconda3/lib/python3.7/site-packages/imagej/imagej.py", line 75, in init
    scyjava_config.add_options('-Djava.awt.headless=true')

  File "/Users/stuart/anaconda3/lib/python3.7/site-packages/scyjava_config.py", line 114, in add_options
    jnius_config.add_options(*opts)

  File "/Users/stuart/anaconda3/lib/python3.7/site-packages/jnius_config.py", line 27, in add_options
    raise ValueError("VM is already running, can't set options")

ValueError: VM is already running, can't set options

Internally, imglyb uses PyJNIus to start a JVM within the Python process. Once import jnius (explicitly or implicitly through imglyb) has been called, the JVM cannot be shutdown or restarted, and a second JVM cannot be launched. This means that you need to start a new Python interpreter before running your code.

It is possible to proceed without installing Apple Java 6; see:

You can edit the Info.plist of any system Java installation (even if it is not the one that will be used by pyimagej) to include <string>JNI</string> in the capabilities section.

Sorry for this hassle, but haven’t had time to pursue a better solution yet.

As @hanslovsky suggests, make sure you are using a freshly launched Python runtime. Does Spyder fork the Python runtime when you launch code? Or does it reuse the runtime? If it reuses the runtime, I’m afraid using pyimagej from Spyder will be trickier.