Rendering a style containing a wktlib reference fails


Rendering a style containing a reference to wktlib:// fails due to an IllegalArgumentException.

The failure is caused when the renderer makes a call to the WKTMarkFactory class

The problem seems to be at line 195: libUrl = new URL(ROOT_DIRECTORY.toString() + "/" + libFile);

The value of ROOT_DIRECTORY is never set after it's initialized, resulting in a null libUrl.

The setRoot(url) method should be called to set the root directory to the Geoserver data directory.




Morgan Thompson
August 4, 2016, 9:47 PM

There seems to be two ways to go about solving this:

1) Change wktlib:// reference to be parsed by the SLDParser as an ExternalGraphic instead of a Mark.

2) Add some logic to the parseMark method in the GeoTools SLDParser to handle the wktlib:// format properly.

Morgan Thompson
August 4, 2016, 10:22 PM

Note that currently if you reference a properties file as below. The symbol defined in the file is rendered correctly. However, as per the ExternalGraphic spec the <Fill> value is ignored as it is expected to be defined within the file.

Option 2 from above could be implemented using logic similar to what is used in parseExternalGraphic

Torben Barsballe
September 9, 2016, 10:02 PM

I've taken a look at this, and a proper fix has some complications:

WKTMarkFactory expects a ROOT_DIRECTORY for wkt properties files.
Where this ROOT_DIRECTORY should be is not clear defined for GeoServer, but the styles directory is assumed. However, we have both a global styles directory and a host of (optional) woorkspaced style directories. Changing the ROOT_DIRECTORY as each style is processed just seems to be asking for a race condition.

If we were to set the ROOT_DIRECTORY, the most appropriate place to do so would be the SLDParser class (which is responsible for parsing the actual SLD file), which has a ResourceLocator that is used to find files (such as external graphics). When using GeoServer, this ResourceLocator is explicitly set to delegate to the GeoServerDataDirecory.

However, the WKT symbol is not actually interpreted until render time, at which point SLDStyleFactory.getShape calls WKTMarkFactory.

As such, having a changing ROOT_DIRECTORY seems to be quite risky.

In light of these issues, I also considered modifying the contents of the Mark name to use a relative URL while interpreting the style with SLDParser. This was discarded as mark name is an Expression, and is thus not guaranteed to have a meaningful value until it is rendered in SLDStyleFactory

The most robust solution I can think of is to modify SLDStyleFactory to have its own ResourceLocator that it uses for stuff like this. However, this would involve an API change (getter/setter for the ResourceLocator) as well as changes in GeoServer to set the ResourceLoader for the SLDStyleFactory.

Another option would be to change the behaviour of WKTMarkFactory to have its own ResourceLocator or equivalent, but that would also be a rather substantial API change.




Morgan Thompson



Fix versions


Affects versions