[Play-2.6 Java] Help with a problem not really related to Play

77 views
Skip to first unread message

Enrico Morelli

unread,
Sep 15, 2017, 10:31:06 AM9/15/17
to Play Framework
I'm developing an application that has to create graph images on fly, Using the application in my computer all works fine. 
When I try to run on the server I receive:

 Unexpected exception[AWTError: Can't connect to X11 window server using '0:0' as the value of the DISPLAY variable.]

I use
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxCellRenderer;
import com.mxgraph.view.mxGraph;
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.image.BufferedImage;

libraries to create the graph. The image is saved on Play public folder and showed under a modal window.
I don't understand why the awt has to access to X11 and I don't know how to solve the problem.

The following is the method called by jquery ajax that creates the image:
public Result getInteractionImage() throws IOException {
        DynamicForm requestData = formFactory.form().bindFromRequest();
        Integer lig_id = Integer.parseInt(requestData.get("lig_id"));
        String typo = requestData.get("typo");
        List<? extends InteractionHbond> interactions;
        if(typo.equals("1")) {
            interactions = ihbond.findByLigId(lig_id);

        } else {
            interactions = ivwd.findByLigId(lig_id);
        }

        //System.out.println(lig_id);
        mxGraph graph = new mxGraph();
        Object parent = graph.getDefaultParent();

        Boolean first = Boolean.TRUE;
        Object v1 = null;
        Object v = null;
        Integer y = 150;
        graph.getModel().beginUpdate();
        List<String> nBorList = new ArrayList<>();
        for (InteractionHbond ib : interactions) {
            for (Atom at : ib.getAtoms()) {

                String[] neigRes = at.getNeigh_atom_str().split(" ");

                if(first) {
                    String[] ligRes = at.getLig_atom_str().split(" ");
                    v1 = graph.insertVertex(parent, null, ligRes[0]+"_"+ligRes[1], 20, 20, 80,
                            30, "shape=ellipse;perimeter=ellipsePerimeter;strokeColor=blank;fillColor=violet");
                    first = Boolean.FALSE;
                }

                if(!nBorList.contains(neigRes[0]+"_"+neigRes[1])) {
                    nBorList.add(neigRes[0]+"_"+neigRes[1]);

                    v = graph.insertVertex(parent, null, neigRes[0]+"_"+neigRes[1], 240, y,
                        80, 30, "shape=ellipse;perimeter=ellipsePerimeter;strokeColor=black;fillColor=orange");

                    graph.insertEdge(parent, null, "", v1, v);

                    y +=50;
                }
            }
        }

        graph.getModel().endUpdate();

        mxGraphComponent graphComponent = new mxGraphComponent(graph);

        BufferedImage image = mxCellRenderer.createBufferedImage(graph, null, 1, Color.white, true, null);
        ImageIO.write(image, "PNG", new File("public/metalweb/images/" + lig_id + "_" + typo + ".png"));
        String img = "<img src=\"/assets/metalweb/images/" + lig_id + "_" + typo + ".png\" >";
        return ok(img);

    }

Is there a solution?

Brian Smith

unread,
Sep 15, 2017, 1:41:33 PM9/15/17
to play-fr...@googlegroups.com
A bunch of native code in java.awt relies on there being a display available.

You can try setting -Djava.awt.headless=true which will cause it to try and run in headless mode and throw if you execute code that needs a display - from distant memory I think that's ok for Images.

If not I think your options are:
- rewrite to avoid AWT 
- run an xhead (maybe one is already running just not accessible on 0:0 i.e. wrong DISPLAY or permissions)

Best of luck.

--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/120a8624-e0ee-4db7-a16f-abfba142d575%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Enrico Morelli

unread,
Sep 18, 2017, 4:06:21 AM9/18/17
to Play Framework


On Friday, September 15, 2017 at 7:41:33 PM UTC+2, BrianS wrote:
A bunch of native code in java.awt relies on there being a display available.

You can try setting -Djava.awt.headless=true which will cause it to try and run in headless mode and throw if you execute code that needs a display - from distant memory I think that's ok for Images.

If not I think your options are:
- rewrite to avoid AWT 
- run an xhead (maybe one is already running just not accessible on 0:0 i.e. wrong DISPLAY or permissions)

Best of luck.


Thank you for you answer. I tried to use the first suggestion but I receive:

play.api.UnexpectedException: Unexpected exception[HeadlessException: null]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:251)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:182)
at play.core.server.AkkaHttpServer$$anonfun$$nestedInanonfun$executeHandler$1$1.applyOrElse(AkkaHttpServer.scala:251)
at play.core.server.AkkaHttpServer$$anonfun$$nestedInanonfun$executeHandler$1$1.applyOrElse(AkkaHttpServer.scala:250)
at scala.concurrent.Future.$anonfun$recoverWith$1(Future.scala:412)
at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at play.api.libs.streams.Execution$trampoline$.executeScheduled(Execution.scala:109)
at play.api.libs.streams.Execution$trampoline$.execute(Execution.scala:71)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68)
Caused by: java.awt.HeadlessException: null
at java.awt.dnd.DragSource.<init>(DragSource.java:258)
at com.mxgraph.swing.handler.mxGraphHandler.installDragGestureHandler(Unknown Source)
at com.mxgraph.swing.handler.mxGraphHandler.<init>(Unknown Source)
at com.mxgraph.swing.mxGraphComponent.createGraphHandler(Unknown Source)
at com.mxgraph.swing.mxGraphComponent.createHandlers(Unknown Source)
at com.mxgraph.swing.mxGraphComponent.<init>(Unknown Source)
at controllers.ResultController.getInteractionImage(ResultController.java:199)
at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$20(Routes.scala:331)
at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:136)
at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:135)




 

Brian Smith

unread,
Sep 18, 2017, 4:14:09 PM9/18/17
to play-fr...@googlegroups.com
I'm afraid it looks like the mxgraph library you're using for generating / processing images touches parts of awt where a display is required, or at least the way you are using it does.

Some ideas:
- try also unsetting DISPLAY in the env, I've seen reports of java ignoring the headless setting if there's a DISPLAY set
- failing that the simplest solution will be to run a display manager or something like xvfb on the server
- you could see if setting various options in mxgraph avoids the calls to awt that need a display (your stack trace indicates you have a component with drag and drop enabled which I'm sure can't be a requirement on server side, can that be configured off?)
- you could use an alternative to mxgraph for generating your images

Hope that helps
Brian


--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.

Enrico Morelli

unread,
Sep 19, 2017, 4:03:08 AM9/19/17
to Play Framework


On Monday, September 18, 2017 at 10:14:09 PM UTC+2, BrianS wrote:
I'm afraid it looks like the mxgraph library you're using for generating / processing images touches parts of awt where a display is required, or at least the way you are using it does.

Some ideas:
- try also unsetting DISPLAY in the env, I've seen reports of java ignoring the headless setting if there's a DISPLAY set
- failing that the simplest solution will be to run a display manager or something like xvfb on the server
- you could see if setting various options in mxgraph avoids the calls to awt that need a display (your stack trace indicates you have a component with drag and drop enabled which I'm sure can't be a requirement on server side, can that be configured off?)
- you could use an alternative to mxgraph for generating your images

Hope that helps
Brian


I tried to unset DISPLAY but I obtain the same exception. In reality the mxgraph (https://jgraph.github.io/mxgraph/docs/manual_javavis.html ) doesn't use awt, I think. I use awt to save image on disk as you see in the method code. I didn't find other way to save the image on disk, if you know other methods I'm happy to know.

Igmar Palsenberg

unread,
Sep 19, 2017, 9:07:16 AM9/19/17
to Play Framework
mxgraph uses X11 to do the actual rendering, and it needs a X11 server running. Your best option : Switch over to something else.


Igmar
 

Enrico Morelli

unread,
Sep 19, 2017, 10:52:50 AM9/19/17
to Play Framework


On Tuesday, September 19, 2017 at 3:07:16 PM UTC+2, Igmar Palsenberg wrote:

mxgraph uses X11 to do the actual rendering, and it needs a X11 server running. Your best option : Switch over to something else.


Igmar
 

Thanks. Someone know an alternative java library to create graph ?
Reply all
Reply to author
Forward
0 new messages