Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eclipse Layout Kernel and version 1.2024.6 #336

Open
arnaudroques opened this issue Jul 8, 2024 · 6 comments
Open

Eclipse Layout Kernel and version 1.2024.6 #336

arnaudroques opened this issue Jul 8, 2024 · 6 comments

Comments

@arnaudroques
Copy link
Contributor

arnaudroques commented Jul 8, 2024

Starting from version 1.2024.6, the Eclipse Layout Kernel (ELK) is now integrated into the main library.

This theoretically means that the following diagram should work out-of-the-box:

@startuml
!pragma layout elk
class red
@enduml

While this works perfectly when running the JAR directly, an issue arises when using the webserver, resulting in the following stack trace:

java.lang.IllegalArgumentException: java.lang.reflect.InvocationTargetException
	at net.sourceforge.plantuml.elk.proxy.Reflect.call2(Reflect.java:227)
	at net.sourceforge.plantuml.elk.proxy.core.RecursiveGraphLayoutEngine.layout(RecursiveGraphLayoutEngine.java:13)
	at net.sourceforge.plantuml.elk.CucaDiagramFileMakerElk.createFile(CucaDiagramFileMakerElk.java:330)
	at net.atmp.CucaDiagram.exportDiagramInternal(CucaDiagram.java:437)
	at net.sourceforge.plantuml.classdiagram.ClassDiagram.exportDiagramInternal(ClassDiagram.java:84)
	at net.sourceforge.plantuml.UmlDiagram.exportDiagramNow(UmlDiagram.java:138)
	at net.sourceforge.plantuml.AbstractPSystem.exportDiagram(AbstractPSystem.java:207)
	at net.sourceforge.plantuml.servlet.DiagramResponse.sendDiagram(DiagramResponse.java:204)
	at net.sourceforge.plantuml.servlet.UmlDiagramService.doDiagramResponse(UmlDiagramService.java:100)
	at net.sourceforge.plantuml.servlet.UmlDiagramService.doGet(UmlDiagramService.java:62)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:500)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587)
	at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1410)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1665)
	at org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:170)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:598)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1570)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1381)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1543)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1303)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:149)
	at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:51)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.Server.handle(Server.java:563)
	at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
	at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at net.sourceforge.plantuml.elk.proxy.Reflect.call2(Reflect.java:224)
	... 51 more
Caused by: org.eclipse.elk.core.UnsupportedConfigurationException: Unable to load default layout algorithm org.eclipse.elk.layered for unconfigured node Root Node
	at org.eclipse.elk.core.data.LayoutAlgorithmResolver.resolveAlgorithm(LayoutAlgorithmResolver.java:61)
	at org.eclipse.elk.core.data.LayoutAlgorithmResolver.visit(LayoutAlgorithmResolver.java:28)
	at org.eclipse.elk.core.util.ElkUtil.applyVisitors(ElkUtil.java:1089)
	at org.eclipse.elk.core.RecursiveGraphLayoutEngine.layout(RecursiveGraphLayoutEngine.java:100)
	at org.eclipse.elk.core.RecursiveGraphLayoutEngine.layout(RecursiveGraphLayoutEngine.java:80)
	... 56 more

Any insights on what might be causing this issue?

@StephanPirnbaum
Copy link

I don't have a solution (yet), but found the same issue with the plantuml plugin for IntelliJ --> esteinberg/plantuml4idea#359 (comment)

While investigating the issue, I stumbled across this post in the plantuml forum --> https://forum.plantuml.net/18998/elk-dont-work

And I can confirm what they wrote (for the IntelliJ plugin atleast). When doing a sequence diagram with ELK, it works, when doing a simple class diagram, it doesn't.

As I believe this has nothing to do with the plantuml-server nor with the IntelliJ plugin, I'll open an issue in the main repository.

@arnaudroques
Copy link
Contributor Author

When doing a sequence diagram with ELK, it works, when doing a simple class diagram, it doesn't.

This happens because ELK isn't used for sequence diagrams—we have our own internal layout engine for those.

Caused by: org.eclipse.elk.core.UnsupportedConfigurationException: Unable to load default layout algorithm org.eclipse.elk.layered for unconfigured node Root Node
	at org.eclipse.elk.core.data.LayoutAlgorithmResolver.resolveAlgorithm(LayoutAlgorithmResolver.java:61)
	at org.eclipse.elk.core.data.LayoutAlgorithmResolver.visit(LayoutAlgorithmResolver.java:28)
	at org.eclipse.elk.core.util.ElkUtil.applyVisitors(ElkUtil.java:1089)
	at org.eclipse.elk.core.RecursiveGraphLayoutEngine.layout(RecursiveGraphLayoutEngine.java:100)
	at org.eclipse.elk.core.RecursiveGraphLayoutEngine.layout(RecursiveGraphLayoutEngine.java:80)
	... 56 more

Unfortunately, we're stuck with this error message. I think only some people from the ELK team could explain what's happening, as everything works fine when we use the JAR directly. Maybe you can give them a call :-)

@arnaudroques
Copy link
Contributor Author

On second thought, we're trying this: 185d5f1
Not sure if it will help, but we'll see! :-)

@StephanPirnbaum
Copy link

Imho, adding the dependencies will not work as otherwise, you'd get a ClassNotFoundException. In the stacktrace you see elk core as part of it.

Before PlantUML contained Elk, you did get a ClassNotFoundException in the IntelliJ plugin which was replaced by the InvocationTargetException when I added the Elk dependencies manually to it. I, however, don't know for sure for the server.

But thanks for the info with the sequence diagram. I didn't know that.

@ahus1
Copy link

ahus1 commented Dec 23, 2024

It seems to me that the lastest versions of ELK don't work with their service loader mechanism assuming a flat class loader.

I've proposed a fix here eclipse-elk/elk#1109 - let's see what the feedback is going to be.

In the meantime, it might be possible to manually register the layout as described here: eclipse-elk/elk#859

I managed to get a similar setup working when trying out the IntelliJ AsciiDoc plugin (which also uses a URL class loader) by patching a JAR like this: https://github.com/ahus1/elk-patched-for-plantuml

@arnaudroques
Copy link
Contributor Author

That's great!
We'll take some time to integrate this into PlantUML, likely in 2025. 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants