When executing a session preview, we can see in the logs

HandleSessionContentUtil - Will write content file....

giving the location where the file gets written to disk. We can also see that this takes place.

Later in the process, we see a java.io.FileNotFoundException thrown by the Page Content Filter, where the filename it's looking for is missing the leftmost 15 characters (not sure if it's always 15, but that's what it is in the example we're looking at)

Our suspicion is this comes from a mismatch in the configurations of two different subsystems, but so far it's not clear what might cause this.

Where should we look to solve this?

2 Answers 2


The reason is that when running the XPM staging website as a WAR, AND have your publish location outside of the WAR, then you need to use the extended document root, AND you need to make this new root path known to ADF so file paths are resolved correctly. Eric Huiza has written about this here. There is a hot fix available for this scenario, the hot fix will allow you to define 4 claims as defined below:

  • full_url: The full http request URL.
  • real_path: The path in the file system for the http request.
  • root_path: The context path.
  • forwarding: Indicates if the http request should be forwarded or not.

These Ambient Data Framework claims should be filled using some custom logic like a Java filter or a .net http module. Does anyone have this implemented and supply Dominic with an example of how to achieve this in Java?

package com.clientname.preview.web.filter;

import com.tridion.ambientdata.AmbientDataContext;
import com.tridion.ambientdata.claimstore.ClaimStore;
import com.tridion.preview.web.PageHandler;
import com.tridion.preview.web.util.AmbientDataUtil;
import com.tridion.preview.web.util.SessionRequestDetails;
import com.tridion.preview.web.util.WebClaims;

import java.io.IOException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class XPMFilter implements Filter {
      private static final Logger log = LoggerFactory.getLogger(XPMFilter.class);

      private static final String PROP_ROOTPATH = "prop/xpmRootPath";

      private ServletContext servletContext;

    public void init(FilterConfig filterConfig) throws ServletException {
        this.servletContext = filterConfig.getServletContext();

    public void doFilter(ServletRequest servletRequest,
            ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;

        String relativePath = httpRequest.getRequestURI();

        if (!AmbientDataUtil.isExcludedPath(relativePath)) {
            ClaimStore claimStore = AmbientDataContext.getCurrentClaimStore();
            if (claimStore != null) {
                String rootPath = null;
                try {
                    Context initialContext = new InitialContext();
                    rootPath = (String) initialContext.lookup(PROP_ROOTPATH);
                    claimStore.put(WebClaims.REQUEST_ROOT_PATH, rootPath);
                    log.debug("Added root path {} with key {} to claim store.", rootPath, WebClaims.REQUEST_ROOT_PATH);
                } catch (NamingException e) {
                    log.debug("Unable to find value for property {} in JNDI, using default root path", PROP_ROOTPATH);
            filterChain.doFilter(httpRequest, httpResponse);

    public void destroy() {


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.