Running Rainbow in Command line with a custom Pipeline opens the GUI

Issue #1356 open
Matija Kovač created an issue

Hi,
I’m building a Flask API server around some of the Okapi functionality. I was having an issue with Tikal and wanted to use more of the advanced functionality available in the Okapi Rainbow, but there are issues when running Rainbow in a headless environment, in my case running the Java subprocess as part of the Python app inside a Docker container.

Here’s an example of a command that works perfectly fine and returns a working XLF file:

rainbow.sh -x TranslationKitCreation -sl en -tl fr someFile.docx -o someFile.docx.xlf

But when trying to run a custom pipeline, like this:

rainbow.sh -pln myPipeline.pln -sl en -tl sl someFile.docx -o someFile.docx.xlf

the system is trying to open the GUI app and since I’m in a headless server I get this error:

Unable to init server: Could not connect: Connection refused
org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]
    at org.eclipse.swt.SWT.error(SWT.java:4944)
    at org.eclipse.swt.widgets.Display.createDisplay(Display.java:1199)
    at org.eclipse.swt.widgets.Display.create(Display.java:1123)
    at org.eclipse.swt.graphics.Device.<init>(Device.java:167)
    at org.eclipse.swt.widgets.Display.<init>(Display.java:632)
    at org.eclipse.swt.widgets.Display.<init>(Display.java:623)
    at net.sf.okapi.applications.rainbow.Main.main(Main.java:30)

I am of course running rainbow.sh with -Djava.awt.headless=true and trying to enforce this both the Docker environment and the function where this command is executed.

So, it works fine with just the -x and the pipeline ID, but it doesn’t work with a pipeline file.
Am I passing the parameters correctly? I tried countless options, such as with and without the -x, putting the pipeline filename in ““ and others, but I always get hit with the same error - Rainbow tries to launch the GUI app.

At this point I’d be happy to look at any workaround as I’ve been dealing with this for too many hours.

Comments (3)

  1. Matija Kovač reporter

    Hi, thanks, but I already tried this and the error persists.

    Here’s the relevant section of my Python code:

     pipelinefile = os.path.join(os.path.dirname(__file__), 'basic_extract_pipeline.pln')
        rainbow_command = [
            './rainbow/rainbow.sh',
            #'-x', 'TranslationKitCreation',
            '-pln', pipelinefile,
            '-sl', source_lang,
            '-tl', target_lang,
            '-opt',
            '-np',
            input_file_path,
            '-o', output_file_path
        ]
        
        # Set Java to run in headless mode
        env = os.environ.copy()
        env["_JAVA_OPTIONS"] = "-Djava.awt.headless=true"
    
        current_app.logger.debug(f"Rainbow Command: {' '.join(rainbow_command)}")  # Debugging output
    
        try:
            result = subprocess.run(rainbow_command, check=True, capture_output=True, text=True, env=env)
            current_app.logger.debug("Rainbow Command Output: %s", result.stdout)  # Debug output stdout
            current_app.logger.debug("Rainbow Command Error: %s", result.stderr)  # Debug output stderr
            return jsonify({
                'message': 'File converted to XLF successfully',
                'xlf_file_url': f'http://{request.host}/get/{folder_name}/{xlf_filename}'
            }), 200
    

    I tried various combinations of pln, opt, np and other params but it always attempts to run the GUI.

    This is the request the above code generated (file names changed for readability):
    Rainbow Command: ./rainbow/rainbow.sh -pln /app/basic_extract_pipeline.pln -sl en -tl sl -opt -np /app/uploads/input_file.docx -o /app/uploads/output_file.docx.xlf

    The error is:
    org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]

    Or more detailed:"Picked up _JAVA_OPTIONS: -Djava.awt.headless=true\nUnable to init server: Could not connect: Connection refused\norg.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]\n\tat org.eclipse.swt.SWT.error(SWT.java:4944)\n\tat org.eclipse.swt.widgets.Display.createDisplay(Display.java:1199)\n\tat org.eclipse.swt.widgets.Display.create(Display.java:1123)\n\tat org.eclipse.swt.graphics.Device.<init>(Device.java:167)\n\tat org.eclipse.swt.widgets.Display.<init>(Display.java:632)\n\tat org.eclipse.swt.widgets.Display.<init>(Display.java:623)\n\tat net.sf.okapi.applications.rainbow.Main.main(Main.java:30)\n"

    In fact, all I’m trying to do is use the <g> notation in order to avoid issues with escaped characters as I’ve mentioned them in a separate issue. It would be nice if I could eventually run other custom pipelines, but for now that’s my only goal.
    I noticed there was another topic here with the same issue and it is supposed to be resolved: okapiframework / #570

    Thanks for looking into this, it would definitely make Okapi much more useful to be able to run it in a server-only mode without going through Longhorn.

  2. Log in to comment