3
votes

I am attempting to style a point layer using a CSS style in geoserver.

Geoserver version 2.11.3 built from a tomcat:8-jre8 docker container (forked from this repo: https://github.com/oscarfonts/docker-geoserver)

My updated docker file (updated geoserver version to 2.11.3 and added some more fonts):

FROM tomcat:8-jre8

MAINTAINER Oscar Fonts <[email protected]>

ENV GEOSERVER_VERSION 2.11.3
ENV GEOSERVER_DATA_DIR /var/local/geoserver
ENV GEOSERVER_INSTALL_DIR /usr/local/geoserver

# Uncomment to use APT cache (requires apt-cacher-ng on host)
#RUN echo "Acquire::http { Proxy \"http://`/sbin/ip route|awk '/default/ { print $3 }'`:3142\"; };" > /etc/apt/apt.conf.d/71-apt-cacher-ng

# Microsoft fonts
# RUN echo "deb http://httpredir.debian.org/debian jessie contrib" >> /etc/apt/sources.list
# RUN set -x \
#   && apt-get update \
#   && apt-get install -yq ttf-mscorefonts-installer \
#   && rm -rf /var/lib/apt/lists/*

# [email protected] -- add other fonts
# based on https://github.com/meteofi/docker-geoserver
ENV NOTO_FONTS="NotoSans-unhinted NotoSerif-unhinted NotoMono-hinted"
ENV GOOGLE_FONTS="Open%20Sans Roboto Lato Ubuntu"
# Install Google Noto fonts
RUN mkdir -p /usr/share/fonts/truetype/noto && \
    for FONT in ${NOTO_FONTS}; \
    do \
        wget -nv https://noto-website.storage.googleapis.com/pkgs/${FONT}.zip && \
        unzip -o ${FONT}.zip -d /usr/share/fonts/truetype/noto && \
        rm -f ${FONT}.zip ; \
    done

# Install Google Fonts
RUN \
    for FONT in $GOOGLE_FONTS; \
    do \
        mkdir -p /usr/share/fonts/truetype/${FONT} && \
        wget -nv -O ${FONT}.zip "https://fonts.google.com/download?family=${FONT}" && \
        unzip -o ${FONT}.zip -d /usr/share/fonts/truetype/${FONT} && \
        rm -f ${FONT}.zip ; \
    done

# Native JAI & ImageIO
RUN cd /usr/lib/jvm/java-8-openjdk-amd64 \
    && wget http://download.java.net/media/jai/builds/release/1_1_3/jai-1_1_3-lib-linux-amd64-jdk.bin \
    && tail -n +139 jai-1_1_3-lib-linux-amd64-jdk.bin > INSTALL-jai \
    && chmod u+x INSTALL-jai \
    && ./INSTALL-jai \
    && rm jai-1_1_3-lib-linux-amd64-jdk.bin INSTALL-jai *.txt \
    && wget http://download.java.net/media/jai-imageio/builds/release/1.1/jai_imageio-1_1-lib-linux-amd64-jdk.bin \
    && tail -n +215 jai_imageio-1_1-lib-linux-amd64-jdk.bin > INSTALL-jai_imageio \
    && chmod u+x INSTALL-jai_imageio \
    && ./INSTALL-jai_imageio \
    && rm jai_imageio-1_1-lib-linux-amd64-jdk.bin INSTALL-jai_imageio *.txt

# GeoServer
ADD conf/geoserver.xml /usr/local/tomcat/conf/Catalina/localhost/geoserver.xml
RUN mkdir ${GEOSERVER_DATA_DIR} \
    && mkdir ${GEOSERVER_INSTALL_DIR} \
    && cd ${GEOSERVER_INSTALL_DIR} \
    && wget http://sourceforge.net/projects/geoserver/files/GeoServer/${GEOSERVER_VERSION}/geoserver-${GEOSERVER_VERSION}-war.zip \
    && unzip geoserver-${GEOSERVER_VERSION}-war.zip \
    && unzip geoserver.war \
    && mv data/* ${GEOSERVER_DATA_DIR} \
    && rm -rf geoserver-${GEOSERVER_VERSION}-war.zip geoserver.war target *.txt

# Enable CORS
RUN sed -i '\:</web-app>:i\
    <filter>\
        <filter-name>CorsFilter</filter-name>\
        <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>\
    </filter>\
\
    <filter-mapping>\
        <filter-name>CorsFilter</filter-name>\
        <url-pattern>/*</url-pattern>\
    </filter-mapping>\
\
    <init-param>\
        <param-name>cors.support.credentials</param-name>\
        <param-value>true</param-value>\
    </init-param>' ${GEOSERVER_INSTALL_DIR}/WEB-INF/web.xml

# Tomcat environment
ENV CATALINA_OPTS "-server -Djava.awt.headless=true \
    -Xms768m -Xmx1560m -XX:+UseConcMarkSweepGC -XX:NewSize=48m \
    -DGEOSERVER_DATA_DIR=${GEOSERVER_DATA_DIR}"

ADD start.sh /usr/local/bin/start.sh
CMD start.sh

EXPOSE 8080

Style definition that is producing error:

/* @title red point */
* {
  mark: url(https://raw.githubusercontent.com/mapbox/maki/master/icons/industry-15.svg);
  mark-mime: "image/svg";
}

[@scale < 2000000] {
  mark-size: 30;
}

[@scale > 2000000] [@scale < 4000000] {
  mark-size: 15;
}

[@scale > 4000000] {
  mark-size: 7.5;
}

For reference, the default point CSS style generated by geoserver does work:

/* @title dark yellow point */
* {
    mark: symbol(square);
    mark-size: 6px;
    :mark {
        fill: #99cc00;
    }
}

Error I'm seeing in geoserver logs:

2017-10-26 16:24:03,845 ERROR [geoserver.ows] - java.lang.NoClassDefFoundError: Could not initialize class org.apache.batik.bridge.CursorManager at org.apache.batik.bridge.BridgeContext.(BridgeContext.java:1154) at org.apache.batik.bridge.BridgeContext.(BridgeContext.java:301) at org.geotools.renderer.style.SVGGraphicFactory$RenderableSVG.getGraphicNode(SVGGraphicFactory.java:401) at org.geotools.renderer.style.SVGGraphicFactory$RenderableSVG.(SVGGraphicFactory.java:345) at org.geotools.renderer.style.SVGGraphicFactory.getIcon(SVGGraphicFactory.java:170) at org.geotools.renderer.style.SLDStyleFactory.getIcon(SLDStyleFactory.java:1350) at org.geotools.renderer.style.SLDStyleFactory.getGraphicStyle(SLDStyleFactory.java:1259) at org.geotools.renderer.style.SLDStyleFactory.createPointStyle(SLDStyleFactory.java:666) at org.geotools.renderer.style.SLDStyleFactory.createPointStyle(SLDStyleFactory.java:546) at org.geotools.renderer.style.SLDStyleFactory.createStyleInternal(SLDStyleFactory.java:381) at org.geotools.renderer.style.SLDStyleFactory.createStyle(SLDStyleFactory.java:328) at org.geoserver.wms.legendgraphic.BufferedImageLegendGraphicBuilder.buildLegendGraphic(BufferedImageLegendGraphicBuilder.java:415) at org.geoserver.wms.decoration.LegendDecoration.findOptimalSize(LegendDecoration.java:136) at org.geoserver.wms.decoration.MapDecorationLayout$Block.findOptimalSize(MapDecorationLayout.java:203) at org.geoserver.wms.decoration.MapDecorationLayout$Block.paint(MapDecorationLayout.java:214) at org.geoserver.wms.decoration.MapDecorationLayout.paint(MapDecorationLayout.java:343) at org.geoserver.wms.map.RenderedImageMapOutputFormat.produceMap(RenderedImageMapOutputFormat.java:571) at org.geoserver.wms.map.RenderedImageMapOutputFormat.produceMap(RenderedImageMapOutputFormat.java:278) at org.geoserver.wms.map.RenderedImageMapOutputFormat.produceMap(RenderedImageMapOutputFormat.java:141) at org.geoserver.wms.GetMap.executeInternal(GetMap.java:623) at org.geoserver.wms.GetMap.run(GetMap.java:279) at org.geoserver.wms.GetMap.run(GetMap.java:125) at org.geoserver.wms.DefaultWebMapService.getMap(DefaultWebMapService.java:320) at sun.reflect.GeneratedMethodAccessor382.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.geoserver.kml.WebMapServiceKmlInterceptor.invoke(WebMapServiceKmlInterceptor.java:34) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.geoserver.gwc.wms.CacheSeedingWebMapService.invoke(CacheSeedingWebMapService.java:62) at org.geoserver.gwc.wms.CacheSeedingWebMapService.invoke(CacheSeedingWebMapService.java:36) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.geoserver.gwc.wms.CachingWebMapService.invoke(CachingWebMapService.java:80) at org.geoserver.gwc.wms.CachingWebMapService.invoke(CachingWebMapService.java:55) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.geoserver.ows.util.RequestObjectLogger.invoke(RequestObjectLogger.java:55) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) at com.sun.proxy.$Proxy24.getMap(Unknown Source) at sun.reflect.GeneratedMethodAccessor318.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.geoserver.ows.Dispatcher.execute(Dispatcher.java:857) at org.geoserver.ows.Dispatcher.handleRequestInternal(Dispatcher.java:268) at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:147) at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859) at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844) at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:423) at org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:169) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.geoserver.filters.ThreadLocalsCleanupFilter.doFilter(ThreadLocalsCleanupFilter.java:28) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:75) at org.geoserver.wms.animate.AnimatorFilter.doFilter(AnimatorFilter.java:71) at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:71) at org.geoserver.filters.SpringDelegatingFilter.doFilter(SpringDelegatingFilter.java:46) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.geoserver.platform.AdvancedDispatchFilter.doFilter(AdvancedDispatchFilter.java:50) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316) at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:69) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:73) at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:69) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:73) at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.geoserver.security.filter.GeoServerAnonymousAuthenticationFilter.doFilter(GeoServerAnonymousAuthenticationFilter.java:54) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:69) at org.springframework.security.web.authentication.www.DigestAuthenticationFilter.doFilter(DigestAuthenticationFilter.java:124) at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:73) at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92) at org.geoserver.security.filter.GeoServerDigestAuthenticationFilter.doFilter(GeoServerDigestAuthenticationFilter.java:88) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.geoserver.security.filter.GeoServerCredentialsFromRequestHeaderFilter.doFilter(GeoServerCredentialsFromRequestHeaderFilter.java:103) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.geoserver.security.GeoServerAuthenticationKeyFilter.doFilter(GeoServerAuthenticationKeyFilter.java:105) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:69) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91) at org.geoserver.security.filter.GeoServerSecurityContextPersistenceFilter$1.doFilter(GeoServerSecurityContextPersistenceFilter.java:53) at org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:73) at org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) at org.geoserver.security.GeoServerSecurityFilterChainProxy.doFilter(GeoServerSecurityFilterChainProxy.java:152) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.geoserver.filters.LoggingFilter.doFilter(LoggingFilter.java:88) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.geoserver.filters.XFrameOptionsFilter.doFilter(XFrameOptionsFilter.java:89) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.geoserver.filters.GZIPFilter.doFilter(GZIPFilter.java:42) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.geoserver.filters.SessionDebugFilter.doFilter(SessionDebugFilter.java:48) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.geoserver.filters.FlushSafeFilter.doFilter(FlushSafeFilter.java:44) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748)

The main error seems to be: java.lang.NoClassDefFoundError: Could not initialize class org.apache.batik.bridge.CursorManager at org.apache.batik.bridge.BridgeContext.

I believe CSS styling was working at one point, so I'm inclined to think it's an issue with my syntax. Any assistance with this issue would be appreciated. Thanks.

2
Are you sure that huge list of errors is related to your CSS? Most of it looks totally unrelated. Do you still get the errors when you remove that CSS?TylerH
What do you mean by "remove that CSS"? That CSS is the style declaration. The layer itself is not at fault; it works when styled with the geoserver default "point" symbology. I'll update the post accordingly.rumski20

2 Answers

3
votes

@Andrea Aime from the geoserver-users mailing list directed me to the solution here: https://solveme.wordpress.com/2017/07/24/java-awt-awterror-assistive-technology-not-found-org-gnome-accessibility-atkwrapper-when-running-jasper-reports/

Adding this line to my dockerfile fixed the issue:

RUN sed -i 's/^assistive_technologies=/#&/' /etc/java-8-openjdk/accessibility.properties
2
votes

It would appear that for whichever reason, GeoServer (or rather, the Apache Batik library) has a problem rendering the SVG file you want to use for the icon:

2017-10-26 16:24:03,845 ERROR [geoserver.ows] - java.lang.NoClassDefFoundError:
 Could not initialize class org.apache.batik.bridge.CursorManager
at org.apache.batik.bridge.BridgeContext.(BridgeContext.java:1154)
at org.apache.batik.bridge.BridgeContext.(BridgeContext.java:301)
at org.geotools.renderer.style.SVGGraphicFactory$RenderableSVG.getGraphicNode(SVGGraphicFactory.java:401)
at org.geotools.renderer.style.SVGGraphicFactory$RenderableSVG.(SVGGraphicFactory.java:345)
at org.geotools.renderer.style.SVGGraphicFactory.getIcon(SVGGraphicFactory.java:170)

I tried your CSS style on my local GeoServer 2.11.2 and it works fine:

enter image description here

I just checked the release artifacts and the Batik dependency seems unchanged between 2.11.2 and 2.11.3 (it's batik-1.7). I also tried to spin up the docker image you've forked, and it seems to include the same batik jars I have. What kind of changes have you done to the image?

(On an unrelated note: which styling would you expect at scales 1:2,000,000 and 1:4,000,000?)