How to use !include with PlantUML Server

0 votes
asked Dec 28, 2018 in Question / help by Justin

I have set up the PlantUml Server according to the instructions at

I am unable to use includes as expected. For example:



class Person {






!include ./Person.puml

Person <|-- Other

class Other


I get an error that says "Error found in diagram Includer
Cannot include ./Person.puml (@ Diagram Line 1, File Line 2)
"!include ./Person.puml"

How do I use file includes with the server?

1 Answer

+1 vote
answered Aug 5, 2019 by bharat (160 points)

Firstly, I would suggest hat don't use ./<filename> - it's cleaner to just do  !include Person.puml and to specify plantuml.include.path with the folder containing that file.

Assuming you are ok with that, the following should work for you

The following method should only be used IF you are running plantuml server on your local laptop via docker and like to use it instead of the jar with say visual studio code simply due to the speed  boost it provides over the jar.  I wouldn't suggest using this on a remote server.

It works on the principle that docker allows you to mount folders on the host as volumes , and thus we are basically mounting the folder with the files to be included as /include inside the container

You probably want to start one container per plantuml project and change the path and port on host accordingly

first start a container - edit the path to the include folder that contains the files you want to include - i usually point it to an include folder in my project

docker run -d -p 8080:8080 -v "<path-to-your-local-include-folder>":/include  --name plantuml plantuml/plantuml-server:jetty

This creates /include inside the container pointing to the folder in your host.

I have deliberately used --name plantuml so that the container is called plantuml for the steps below. Use any name as required, e.g. your project /workspace name for easy reference.

we then need to edit the jetty.start file to pickup this folder

create a new file called jetty.start with the following content (single line)- the bits I have highlighted in red are the options that I have added to the existing jetty.start that comes with the container- you only need the -Dplantuml.include.path=/include option in there - the rest are various useful tunings that i tend to use - edit as required (e.g. i notice in docker stats that the container tends to go higher than 256M on first invocation while on startup is around 133M, so hence set the minimal  to 256M accordingly.

/usr/local/openjdk-8/bin/java -Xms256M -Xss256M -Xmn512M -Xmx1024M -DPLANTUML_LIMIT_SIZE=8192 -Dplantuml.include.path=/include -Djetty.home=/usr/local/jetty -Djetty.base=/var/lib/jetty -cp /usr/local/jetty/lib/mail/javax.mail.glassfish-1.4.1.v201005082020.jar:/var/lib/jetty/resources:/usr/local/jetty/lib/servlet-api-3.1.jar:/usr/local/jetty/lib/jetty-schemas-3.1.jar:/usr/local/jetty/lib/jetty-http-9.4.18.v20190429.jar:/usr/local/jetty/lib/jetty-server-9.4.18.v20190429.jar:/usr/local/jetty/lib/jetty-xml-9.4.18.v20190429.jar:/usr/local/jetty/lib/jetty-util-9.4.18.v20190429.jar:/usr/local/jetty/lib/jetty-io-9.4.18.v20190429.jar:/usr/local/jetty/lib/jetty-jndi-9.4.18.v20190429.jar:/usr/local/jetty/lib/jetty-security-9.4.18.v20190429.jar:/usr/local/jetty/lib/transactions/javax.transaction-api-1.3.jar:/usr/local/jetty/lib/jetty-servlet-9.4.18.v20190429.jar:/usr/local/jetty/lib/jetty-webapp-9.4.18.v20190429.jar:/usr/local/jetty/lib/jetty-plus-9.4.18.v20190429.jar:/usr/local/jetty/lib/jetty-annotations-9.4.18.v20190429.jar:/usr/local/jetty/lib/annotations/asm-7.0.jar:/usr/local/jetty/lib/annotations/asm-analysis-7.0.jar:/usr/local/jetty/lib/annotations/asm-commons-7.0.jar:/usr/local/jetty/lib/annotations/asm-tree-7.0.jar:/usr/local/jetty/lib/annotations/javax.annotation-api-1.3.jar:/usr/local/jetty/lib/apache-jsp/org.eclipse.jdt.ecj-3.17.0.jar:/usr/local/jetty/lib/apache-jsp/org.eclipse.jetty.apache-jsp-9.4.18.v20190429.jar:/usr/local/jetty/lib/apache-jsp/org.mortbay.jasper.apache-el-8.5.40.jar:/usr/local/jetty/lib/apache-jsp/org.mortbay.jasper.apache-jsp-8.5.40.jar:/usr/local/jetty/lib/apache-jstl/org.apache.taglibs.taglibs-standard-impl-1.2.5.jar:/usr/local/jetty/lib/apache-jstl/org.apache.taglibs.taglibs-standard-spec-1.2.5.jar:/usr/local/jetty/lib/jetty-client-9.4.18.v20190429.jar:/usr/local/jetty/lib/jetty-deploy-9.4.18.v20190429.jar:/usr/local/jetty/lib/websocket/javax.websocket-api-1.0.jar:/usr/local/jetty/lib/websocket/javax-websocket-client-impl-9.4.18.v20190429.jar:/usr/local/jetty/lib/websocket/javax-websocket-server-impl-9.4.18.v20190429.jar:/usr/local/jetty/lib/websocket/websocket-api-9.4.18.v20190429.jar:/usr/local/jetty/lib/websocket/websocket-client-9.4.18.v20190429.jar:/usr/local/jetty/lib/websocket/websocket-common-9.4.18.v20190429.jar:/usr/local/jetty/lib/websocket/websocket-server-9.4.18.v20190429.jar:/usr/local/jetty/lib/websocket/websocket-servlet-9.4.18.v20190429.jar org.eclipse.jetty.xml.XmlConfiguration java.version=1.8.0_212 java.version.major=1 java.version.micro=0 java.version.minor=8 java.version.platform=8 jetty.base=/var/lib/jetty jetty.base.uri=file:///var/lib/jetty jetty.home=/usr/local/jetty jetty.home.uri=file:///usr/local/jetty /usr/local/jetty/etc/jetty-bytebufferpool.xml /usr/local/jetty/etc/jetty-threadpool.xml /usr/local/jetty/etc/jetty.xml /usr/local/jetty/etc/jetty-webapp.xml /usr/local/jetty/etc/jetty-plus.xml /usr/local/jetty/etc/jetty-annotations.xml /usr/local/jetty/etc/jetty-deploy.xml /usr/local/jetty/etc/jetty-http.xml

use docker cp to update jetty.start

docker cp <path to jetty start on your local>/jetty.start plantuml:/var/lib/jetty/.

and then

docker stop plantuml

docker start plantuml

to restart the container to pickup the changes

Once done - test it - on VSCode, plantuml preview picked it up in a second and is lightning fast now

if you are happy with this then

docker commit plantuml plantuml/plantuml-server:jetty

so that this is preserved inside your local image- so that when you spin additional containers for other projects it picks up the include folder specified in the volume

Obviously if you messup your image, simply delete the local dockermage using docker image rm (remember to docker stop <containername>, docker rm <containername> first!) and use docker run  again so that the original image is fetched from dockerhub. Repeat and rinse and hopefully it works this time

If you need to  add folders in your include path than just one you should be able to specify it like this seperated by a  colon in the java args (inside jetty.start) - I haven't tried this but this is referred from

-Dplantuml.include.path=<folder path1>:<folderpath2>

and for each path you can map it as a volume in your docker startup using one -v argument per volume

Hope this helps!

P.S : I am probably breaking a couple of rules here - this link

does suggest that i can pass environment variables to plantuml running in the docker image using -e , however i couldn't get it to work unfortunately hence had to resort to  editing jetty.start - i assume that only specific environent variables are allowed by default so it wouldn't pickup the plantuml.include.path by default without me tweaking the dockerfile script.

commented Oct 31, 2019 by bharat (160 points)
An update - the above stops working with the new war file 1.2019.11 as per my comment here

Looks like the use of include is not that popular :(. It's a pity as it lets you break your diagram into smaller manageable chunks
commented Jun 1 by jaya (100 points)
I got it working using environment variables as an alternative

docker run -d -p 8080:8080 -e ALLOW_PLANTUML_INCLUDE=true -e _JAVA_OPTIONS="-Dplantuml.include.path=/include" -v "<path-to-your-local-include-folder>":/include  --name plantuml plantuml/plantuml-server:jetty

Also note if you want to modify jetty.start instead, that you will need to update the jetty file based off the latest plantuml-server docker image. One way to get this is from remoting in to the container docker exec -it plantuml /bin/bash and cat ~/jetty.start
commented Jul 21 by anonymous

Use "plantuml.includeSearch": "Relative", in your .vscode/settings.json file to allow relative includes. Note that search is not recursive, so you have to specify the path from your include path (above) in !include <relative path>/file.puml