cantaloupe-project / cantaloupe

High-performance dynamic image server in Java
https://cantaloupe-project.github.io/
Other
267 stars 107 forks source link

Admin web page links do not seem to be working #149

Closed imoutsatsos closed 6 years ago

imoutsatsos commented 7 years ago

I have identified an issue in the latest develop branch. The links on the side of the admin web page do not work. image They all end up here: image

adolski commented 7 years ago

Works for me. Do you have base_uri set, or an incorrect X-Forwarded-Path header? In the log output, what does Base URI assembled from... say?

imoutsatsos commented 7 years ago

base_uri is NOT set. I'm using a properties file from the previous release that was working. When I switch to the previous version it still works fine, and 'Base URI assmbled from ...' is identical.

Here are the console logs from working and failing version untitled_clipping_082517_093225_am

adolski commented 7 years ago

Hmmm, I'm not sure what that is. My best guess is that processor.fallback is not set? Even if I'm wrong, there have been some changes to the config keys in 3.4 and it would probably be good to either:

  1. Make a copy of your config file and in the copy, carry out the steps in the "From 3.3.3 to 3.4" section here: https://github.com/medusa-project/cantaloupe/blob/develop/website/upgrade.html -- then use the copy as your config file with version 3.4-SNAPSHOT.
  2. Alternatively, you could fill in the sample config file for 3.4: https://github.com/medusa-project/cantaloupe/blob/develop/cantaloupe.properties.sample
imoutsatsos commented 7 years ago

Hi again. I have taken step 2 above and transferred some of my old settings. I'm still getting the same error.

The processor.fallback=Java2dProcessor

adolski commented 7 years ago

What browser are you using and is JavaScript enabled? (I assume so because it works for you in 3.3, but, just to confirm)

imoutsatsos commented 7 years ago

Using Chrome Version 59.0.3071.86 (Official Build) (32-bit) and yes Javascript is enabled

adolski commented 7 years ago

This should be fixed now in develop and release/3.3 branches. I think it was caused by incorrect hash URLs generated in conjunction with the <base> tag. As far as I can tell, the links should have been intercepted by Bootstrap before they would become apparent, and I'm not sure why they weren't in your case.

Please reopen if you find the fix unsuccessful. Thanks for reporting.

imoutsatsos commented 7 years ago

Thank you for your work on this! I have compiled and tried the latest version, but the links still do not seem to work. Essentially the same error. However, this time I'm not redirected to the logo page. Just get the error:

java.io.IOException: Template processing error. Invocation of method 'supports' in  class edu.illinois.library.cantaloupe.resource.admin.AdminResource$ProcessorProxy threw exception java.lang.NullPointerException at org.restlet.resource.representation[line 1, column 64201]
    at org.restlet.ext.velocity.TemplateRepresentation.write(TemplateRepresentation.java:401)
    at org.restlet.representation.CharacterRepresentation.write(CharacterRepresentation.java:67)
    at org.restlet.engine.adapter.ServerCall.writeResponseBody(ServerCall.java:513)
    at org.restlet.engine.adapter.ServerCall.sendResponse(ServerCall.java:457)
    at org.restlet.ext.servlet.internal.ServletCall.sendResponse(ServletCall.java:421)
    at org.restlet.engine.adapter.ServerAdapter.commit(ServerAdapter.java:191)
    at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:144)
    at org.restlet.ext.servlet.ServerServlet.service(ServerServlet.java:1117)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:833)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:535)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:564)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:317)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
    at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:128)
    at org.eclipse.jetty.util.thread.Invocable$InvocableExecutor.invoke(Invocable.java:222)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:294)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:199)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:673)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:591)
    at java.lang.Thread.run(Unknown Source)
kinow commented 6 years ago

Just checked out the latest code, on Ubuntu LTS + JDK 8, and it works on Firefox and Chrome.

Here's my cantaloupe.properties.

###########################################################################
# Sample Cantaloupe configuration file
#
# Copy this file to `cantaloupe.properties` and edit as desired.
#
# Most changes will take effect without restarting. Those that won't are
# marked with "!!".
###########################################################################

# !! Whether to enable HTTP access (http://), and on what host interface
# and TCP port. (Applies in standalone mode only.)
http.enabled = true
http.host = 0.0.0.0
http.port = 8182
http.http2.enabled = true

# !! Whether to enable HTTPS access (https://), and on what host interface
# and TCP port. (Applies in standalone mode only.)
https.enabled = false
https.host = 0.0.0.0
https.port = 8183
https.http2.enabled = true

# !! Available values are `JKS` and `PKCS12`. (Standalone mode only.)
https.key_store_type = JKS
https.key_store_password = myPassword
https.key_store_path = /path/to/keystore.jks
https.key_password = myPassword

# !! Maximum size of the HTTP(S) request queue. Set to 0 to use the OS
# default.
http.accept_queue_limit = 0

# !! Configures HTTP Basic authentication.
auth.basic.enabled = true
auth.basic.username = admin
auth.basic.secret = admin

# Enables the Control Panel, at /admin.
admin.enabled = true
# Password to access the Control Panel. (The username is "admin".)
admin.password = admin

# Base URI to use for internal links, such as Link headers and JSON-LD @id
# values, in a reverse-proxy context. This should only be used when
# X-Forwarded-* headers cannot be used instead (see the user manual).
base_uri =

# Normally, slashes in a URI path component must be percent-encoded as
# "%2F". If your proxy is incapable of passing these through without
# decoding them, you can define an alternate character or character
# sequence to substitute for a slash. Supply the non-percent-encoded
# version here, and use the percent-encoded version in URLs.
slash_substitute =

# Maximum number of pixels to return in a response, to prevent overloading
# the server. Requests for more pixels than this will receive an error
# response. Set to 0 for no maximum.
max_pixels = 400000000

# Sometimes helpful.
print_stack_trace_on_error_pages = true

###########################################################################
# DELEGATE SCRIPT
###########################################################################

# !! Enables the delegate script: a Ruby script containing various delegate
# methods. (See the user manual.)
delegate_script.enabled = false

# !! This can be an absolute path, or a filename; if only a
# filename is specified, it will be searched for in the same folder as this
# file, and then the current working directory.
delegate_script.pathname = delegates.rb

# Enables the invocation cache, which caches method invocations and
# return values in memory. See the user manual for more information.
delegate_script.cache.enabled = false

###########################################################################
# ENDPOINTS
###########################################################################

endpoint.iiif.1.enabled = true

endpoint.iiif.2.enabled = true

# Controls the response Content-Disposition header for images. Allowed
# values are `inline`, `attachment`, and `none`.
endpoint.iiif.content_disposition = inline

# Minimum size that will be used in info.json "tiles" keys. See the user
# manual for an explanation of how these are calculated.
endpoint.iiif.min_tile_size = 1024

# If true, requests for sizes other than those specified in an info.json
# response will be denied.
endpoint.iiif.2.restrict_to_sizes = false

# Enables the administrative REST API. (See the user manual.)
endpoint.api.enabled = false

# HTTP Basic credentials to access the REST API.
endpoint.api.username =
endpoint.api.secret =

###########################################################################
# RESOLVERS
###########################################################################

# Specifies one resolver to translate the identifier in the URL to an image
# source for all requests. Available values are `FilesystemResolver`,
# `HttpResolver`, `JdbcResolver`, `AmazonS3Resolver`, and
# `AzureStorageResolver`.
resolver.static = FilesystemResolver

# If true, `resolver.static` will be overridden, and the
# `get_resolver(identifier)` delegate script method will be used to select
# a resolver per-request.
resolver.delegate = false

#----------------------------------------
# FilesystemResolver
#----------------------------------------

# Tells FilesystemResolver how to look up files. Allowed values are
# `BasicLookupStrategy` and `ScriptLookupStrategy`. ScriptLookupStrategy
# uses the delegate script for dynamic lookups; see the user manual for
# details.
FilesystemResolver.lookup_strategy = BasicLookupStrategy

# Server-side path that will be prefixed to the identifier in the URL.
# Trailing slash is important.
FilesystemResolver.BasicLookupStrategy.path_prefix = /home/kinow/Pictures/

# Server-side path or extension that will be suffixed to the identifier in
# the URL.
FilesystemResolver.BasicLookupStrategy.path_suffix =

#----------------------------------------
# HttpResolver
#----------------------------------------

# Whether to trust invalid certificates when making HTTPS connections.
HttpResolver.trust_invalid_certs = false

# Tells HttpResolver how to look up resources. Allowed values are
# `BasicLookupStrategy` and `ScriptLookupStrategy`. ScriptLookupStrategy
# uses the delegate script for dynamic lookups; see the user manual for
# details.
HttpResolver.lookup_strategy = BasicLookupStrategy

# URL that will be prefixed to the identifier in the request URL. Trailing
# slash is important.
HttpResolver.BasicLookupStrategy.url_prefix = http://localhost/images/

# Path, extension, query string, etc. that will be suffixed to the
# identifier in the request URL.
HttpResolver.BasicLookupStrategy.url_suffix =

# Used for HTTP Basic authentication.
HttpResolver.auth.basic.username =
HttpResolver.auth.basic.secret =

#----------------------------------------
# JdbcResolver
#----------------------------------------

# Note: JdbcResolver requires some delegate methods to be implemented in
# addition to the configuration here; see the user manual.

# !!
JdbcResolver.url = jdbc:postgresql://localhost:5432/my_database
# !!
JdbcResolver.user = postgres
# !!
JdbcResolver.password = postgres

# !! Connection timeout in seconds.
JdbcResolver.connection_timeout = 10

#----------------------------------------
# AmazonS3Resolver
#----------------------------------------

# !! Access key ID and secret key associated with your AWS account.
# See: http://aws.amazon.com/security-credentials
AmazonS3Resolver.access_key_id =
AmazonS3Resolver.secret_key =

# !! Name of the bucket containing images to be served.
AmazonS3Resolver.bucket.name =

# !! Can be left blank.
# See: http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
AmazonS3Resolver.bucket.region =

# Tells AmazonS3Resolver how to look up objects. Allowed values are
# `BasicLookupStrategy` and `ScriptLookupStrategy`. ScriptLookupStrategy
# uses the delegate script for dynamic lookups; see the user manual for
# details.
AmazonS3Resolver.lookup_strategy = BasicLookupStrategy

#----------------------------------------
# AzureStorageResolver
#----------------------------------------

# !! Name of your Azure account.
AzureStorageResolver.account_name =

# !! Key of your Azure account.
AzureStorageResolver.account_key =

# !! Name of the container containing images to be served.
AzureStorageResolver.container_name =

# Tells AzureStorageResolver how to look up objects. Allowed values are
# `BasicLookupStrategy` and `ScriptLookupStrategy`. ScriptLookupStrategy
# uses the delegate script for dynamic lookups; see the user manual for
# details.
AzureStorageResolver.lookup_strategy = BasicLookupStrategy

###########################################################################
# PROCESSORS
###########################################################################

#----------------------------------------
# Processor Selection
#----------------------------------------

# Image processors to use for various source formats. Available values are
# `Java2dProcessor`, `GraphicsMagickProcessor`, `ImageMagickProcessor`,
# `KakaduProcessor`, `OpenJpegProcessor`, `JaiProcessor`, `PdfBoxProcessor`,
# and `FfmpegProcessor`.

# These extension-specific definitions are optional.
processor.avi = FfmpegProcessor
processor.bmp =
processor.dcm =
processor.gif =
processor.jp2 = KakaduProcessor
processor.jpg =
processor.mov = FfmpegProcessor
processor.mp4 = FfmpegProcessor
processor.mpg = FfmpegProcessor
processor.pdf = PdfBoxProcessor
processor.png =
processor.sgi = ImageMagickProcessor
processor.tif =
processor.webm = FfmpegProcessor
processor.webp = ImageMagickProcessor

# Fall back to this processor for any formats not assigned above.
processor.fallback = Java2dProcessor

#----------------------------------------
# Global Processor Configuration
#----------------------------------------

# Expands contrast to utilize available dynamic range. This forces the entire
# source image to be read into memory, so can be slow with large images.
processor.normalize = false

# Color of the background when an image is rotated or alpha-flattened, for
# output formats that do not support transparency.
processor.background_color = black

# Available values are `bell`, `bspline`, `bicubic`, `box`, `hermite`,
# `lanczos3`, `mitchell`, `triangle`. (These are not used by JaiProcessor.)
processor.downscale_filter = bicubic
processor.upscale_filter = bicubic

# Intensity of an unsharp mask from 0 to 1.
processor.sharpen = 0

# Attempts to copy source image metadata (EXIF, IPTC, XMP) into derivative
# images. (This is not foolproof; see the user manual.)
processor.metadata.preserve = false

# Whether to auto-rotate images using the EXIF "Orientation" field.
# The check for this field can impair performance slightly.
processor.metadata.respect_orientation = false

# Progressive JPEGs are generally more space-efficient.
processor.jpg.progressive = true

# JPEG output quality (1-100).
processor.jpg.quality = 80

# TIFF output compression type. Available values are `Deflate`, `JPEG`,
# `LZW`, and `RLE`. Leave blank for no compression.
processor.tif.compression = LZW

# Available values are `StreamStrategy` and `CacheStrategy`. StreamStrategy
# will try to stream source images from non-filesystem resolvers, when this
# is possible; CacheStrategy will first download them into the source cache
# using FilesystemCache, which must also be configured.
StreamProcessor.retrieval_strategy = StreamStrategy

#----------------------------------------
# FfmpegProcessor
#----------------------------------------

# Optional absolute path of the directory containing the FFmpeg binaries.
# Overrides the PATH.
FfmpegProcessor.path_to_binaries =

#----------------------------------------
# GraphicsMagickProcessor
#----------------------------------------

# !! Optional absolute path of the directory containing the GraphicsMagick
# binary. Overrides the PATH.
GraphicsMagickProcessor.path_to_binaries =

#----------------------------------------
# ImageMagickProcessor
#----------------------------------------

# !! Optional absolute path of the directory containing the ImageMagick
# binaries. Overrides the PATH.
ImageMagickProcessor.path_to_binaries = /usr/bin

#----------------------------------------
# KakaduProcessor
#----------------------------------------

# Optional absolute path of the directory containing the Kakadu binaries.
# Overrides the PATH.
KakaduProcessor.path_to_binaries =

#----------------------------------------
# OpenJpegProcessor
#----------------------------------------

# Optional absolute path of the directory containing the OpenJPEG binaries.
# Overrides the PATH.
OpenJpegProcessor.path_to_binaries =

#----------------------------------------
# PdfBoxProcessor
#----------------------------------------

# Resolution of the PDF rasterization at a scale of 1. Requests for
# scales less than 0.5 or larger than 2 will automatically use a lower or
# higher factor of this.
PdfBoxProcessor.dpi = 150

###########################################################################
# CLIENT-SIDE CACHING
###########################################################################

# Whether to enable the response Cache-Control header.
cache.client.enabled = true

cache.client.max_age = 2592000
cache.client.shared_max_age =
cache.client.public = true
cache.client.private = false
cache.client.no_cache = false
cache.client.no_store = false
cache.client.must_revalidate = false
cache.client.proxy_revalidate = false
cache.client.no_transform = true

###########################################################################
# SERVER-SIDE CACHING
###########################################################################

# Enables the source cache. Note that source images will only be cached
# when a FileProcessor is used with a StreamResolver, or when a
# StreamProcessor is used with `StreamProcessor.retrieval_strategy` set to
# `CacheStrategy`.
cache.server.source.enabled = false

# FilesystemCache is the only available source cache.
cache.server.source = FilesystemCache

# Enables the derivative (processed image) cache.
cache.server.derivative.enabled =

# Available values are `FilesystemCache`, `JdbcCache`, `AmazonS3Cache`, and
# `AzureStorageCache`.
cache.server.derivative =

# Time before a cached image becomes stale and needs to be reloaded. Set to
# blank or 0 for infinite.
cache.server.ttl_seconds = 2592000

# If true, when a resolver reports that the requested source image has gone
# missing, all cached information relating to it (if any) will be deleted.
# (This is effectively always false when cache.server.resolve_first is also
# false.)
cache.server.purge_missing = false

# If true, the source image will be confirmed to exist before a cached copy
# is returned. If false, the cached copy will be returned without any
# checking. Resolving first is slower but safer.
cache.server.resolve_first = false

# !! Enables the cache worker, which periodically purges expired cache
# items in the background.
cache.server.worker.enabled = false

# !! The cache worker will wait this many seconds between purgings.
cache.server.worker.interval = 86400

#----------------------------------------
# FilesystemCache
#----------------------------------------

# If this directory does not exist, it will be created automatically.
FilesystemCache.pathname = /var/cache/cantaloupe

# Levels of folder hierarchy in which to store cached images. Deeper depth
# results in fewer files per directory. Set to 0 to disable subfolders.
# Purge the cache after changing this.
FilesystemCache.dir.depth = 3

# Number of characters in hierarchy directory names. Should be set to
# 16^n < (max number of directory entries your filesystem can deal with).
# Purge the cache after changing this.
FilesystemCache.dir.name_length = 2

#----------------------------------------
# HeapCache
#----------------------------------------

# Target cache size, in bytes or a number ending in M, MB, G, GB, etc.
# This is not a hard limit, and may be transiently exceeded.
# Ensure your heap can accommodate this size using the -Xmx= VM argument.
HeapCache.target_size = 2G

# If true, the cache contents will be written to a file on exit, and read
# back in at startup.
HeapCache.persist = false

# When the contents are persisted, this specifies the location of the cache
# file. If the parent directory does not exist, it will be created
# automatically.
HeapCache.persist.filesystem.pathname = /var/cache/cantaloupe/heap.cache

#----------------------------------------
# JdbcCache
#----------------------------------------

# !!
JdbcCache.url = jdbc:postgresql://localhost:5432/cantaloupe
# !!
JdbcCache.user = postgres
# !!
JdbcCache.password =

# !! Connection timeout in seconds.
JdbcCache.connection_timeout = 10

# These must be created manually; see the user manual.
JdbcCache.derivative_image_table = derivative_cache
JdbcCache.info_table = info_cache

#----------------------------------------
# AmazonS3Cache
#----------------------------------------

# !! Access key ID and secret key associated with your AWS account.
# See: http://aws.amazon.com/security-credentials
AmazonS3Cache.access_key_id =
AmazonS3Cache.secret_key =

# !! Name of a bucket to use to hold cached data.
AmazonS3Cache.bucket.name =

# !! Can be left blank.
# See: http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
AmazonS3Cache.bucket.region =

# !! String that will be prefixed to object keys.
AmazonS3Cache.object_key_prefix =

#----------------------------------------
# AzureStorageCache
#----------------------------------------

# !! Name of your Azure account.
AzureStorageCache.account_name =

# !! Key of your Azure account.
AzureStorageCache.account_key =

# !! Name of the container containing cached images.
AzureStorageCache.container_name =

# !! String that will be prefixed to object keys.
AzureStorageCache.object_key_prefix =

#----------------------------------------
# RedisCache
#----------------------------------------

# !! Redis host.
RedisCache.host = localhost

# !! Redis port.
RedisCache.port = 6379

# !! Whether to connect via SSL.
RedisCache.ssl = false

# !! Redis connection password. Leave blank for no password.
RedisCache.password =

# !! Database to use.
RedisCache.database = 0

###########################################################################
# OVERLAYS
###########################################################################

# Whether to enable overlays.
overlays.enabled = false

# Specifies how overlays are configured. `BasicStrategy` will use the
# `overlays.BasicStrategy.*` keys in this section. `ScriptStrategy` will
# use the `overlay` delegate method. See the user manual for more
# information.
overlays.strategy = BasicStrategy

# `image` or `string`.
overlays.BasicStrategy.type = image

# Absolute path or URL of the overlay image. Must be a PNG file.
overlays.BasicStrategy.image = /path/to/overlay.png

# Overlay text.
overlays.BasicStrategy.string = Copyright \u00A9️ My Great Organization\nAll rights reserved.

# For possible values, launch with the -Dcantaloupe.list_fonts option.
overlays.BasicStrategy.string.font = Helvetica

# Font size in points.
overlays.BasicStrategy.string.font.size = 24

# If the string doesn't fit in the image at the above size, the largest size
# at which it does fit will be used, down to this.
overlays.BasicStrategy.string.font.min_size = 18

# Font weight. 1 = regular, 2 = bold. Note that many fonts don't support
# fractional weights.
overlays.BasicStrategy.string.font.weight = 1.0

# Point spacing between glyphs, typically between -0.1 and 0.1.
overlays.BasicStrategy.string.glyph_spacing = 0.02

# CSS color syntax is supported.
overlays.BasicStrategy.string.color = white

# CSS color syntax is supported.
overlays.BasicStrategy.string.stroke.color = black

# Stroke width in pixels.
overlays.BasicStrategy.string.stroke.width = 1

# Color of a background to draw under the string.
# CSS color syntax is supported.
overlays.BasicStrategy.string.background.color = rgba(0, 0, 0, 100)

# Allowed values: `top left`, `top center`, `top right`, `left center`,
# `center`, `right center`, `bottom left`, `bottom center`, `bottom right`.
overlays.BasicStrategy.position = bottom right

# Pixel margin between the overlay and the image edge.
overlays.BasicStrategy.inset = 10

# Output images less than this many pixels wide will not receive an overlay.
# Set to 0 to add the overlay regardless.
overlays.BasicStrategy.output_width_threshold = 400

# Output images less than this many pixels tall will not receive an overlay.
# Set to 0 to add the overlay regardless.
overlays.BasicStrategy.output_height_threshold = 300

###########################################################################
# REDACTIONS
###########################################################################

# Whether to enable redactions. See the user manual for information about
# how these work.
redaction.enabled = false

###########################################################################
# LOGGING
###########################################################################

#----------------------------------------
# Application Log
#----------------------------------------

# `trace`, `debug`, `info`, `warn`, `error`, `all`, or `off`
log.application.level = debug

log.application.ConsoleAppender.enabled = true

log.application.FileAppender.enabled = false
log.application.FileAppender.pathname = /path/to/logs/combined-application.log

log.application.RollingFileAppender.enabled = false
log.application.RollingFileAppender.pathname = /path/to/logs/rolling-application.log
log.application.RollingFileAppender.policy = TimeBasedRollingPolicy
log.application.RollingFileAppender.TimeBasedRollingPolicy.filename_pattern = /path/to/logs/rolling-application-%d{yyyy-MM-dd}.log
log.application.RollingFileAppender.TimeBasedRollingPolicy.max_history = 30

# See the "SyslogAppender" section for a list of facilities:
# http://logback.qos.ch/manual/appenders.html
log.application.SyslogAppender.enabled = false
log.application.SyslogAppender.host =
log.application.SyslogAppender.port = 514
log.application.SyslogAppender.facility = LOCAL0

#----------------------------------------
# Error Log
#----------------------------------------

# Application log messages with a severity of WARN or greater can be copied
# into a dedicated error log, which may make them easier to spot.

log.error.FileAppender.enabled = false
log.error.FileAppender.pathname = /path/to/logs/combined-error.log

log.error.RollingFileAppender.enabled = false
log.error.RollingFileAppender.pathname = /path/to/logs/rolling-app.log
log.error.RollingFileAppender.policy = TimeBasedRollingPolicy
log.error.RollingFileAppender.TimeBasedRollingPolicy.filename_pattern = /path/to/logs/rolling-app-%d{yyyy-MM-dd}.log
log.error.RollingFileAppender.TimeBasedRollingPolicy.max_history = 30

#----------------------------------------
# Access Log
#----------------------------------------

log.access.ConsoleAppender.enabled = false

log.access.FileAppender.enabled = false
log.access.FileAppender.pathname = /path/to/logs/access.log

# RollingFileAppender is an alternative to using something like
# FileAppender + logrotate.
log.access.RollingFileAppender.enabled = false
log.access.RollingFileAppender.pathname = /path/to/logs/access.log
log.access.RollingFileAppender.policy = TimeBasedRollingPolicy
log.access.RollingFileAppender.TimeBasedRollingPolicy.filename_pattern = /path/to/logs/access-%d{yyyy-MM-dd}.log
log.access.RollingFileAppender.TimeBasedRollingPolicy.max_history = 30

# See the "SyslogAppender" section for a list of facilities:
# http://logback.qos.ch/manual/appenders.html
log.access.SyslogAppender.enabled = false
log.access.SyslogAppender.host =
log.access.SyslogAppender.port = 514
log.access.SyslogAppender.facility = LOCAL0
kinow commented 6 years ago

Tested on Windows 10, same git commit, JDK 8. same property file, different only the imagemagick path (7.0.7-7-portable-Q16-x64). Worked on Chrome, Firefox, and IE Edge. Hope that helps.

adolski commented 6 years ago

This issue may really be two separate issues (links not working and java.io.IOException: Template processing error. Invocation of method 'supports' in class edu...)

Well, better late than never I hope, but I was finally able to reproduce the IOException. It was caused by the Control Panel endpoint failing to catch an InitializationException thrown by a processor in use that can't initialize itself -- like if ImageMagickProcessor was assigned to a format and ImageMagick was not installed. The handling is now improved so that that shouldn't happen anymore.

No updates on the links not working, though... I've still never been able to reproduce that.

adolski commented 6 years ago

I was finally able to reproduce the broken links. The admin template contains a method call that could throw a NullPointerException when a processor fails to initialize itself, which would cause a partially-rendered template to be returned. But the <script> tags (including the one referencing the script that makes the tabs work) are at the end of the template, so they wouldn't get sent. This should now be fixed. Thanks all.