| // ======================================================================== |
| // Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. |
| // ======================================================================== |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| |
| [[troubleshooting-locked-files-on-windows]] |
| === Troubleshooting Locked Files on Windows |
| |
| Jetty buffers static content for webapps such as HTML files, CSS files, images, etc. |
| If you are using NIO connectors, Jetty uses memory-mapped files to do this. |
| The problem is that on Windows, memory mapping a file causes the file to lock, so that you cannot update or replace the file. |
| Effectively this means that you have to stop Jetty to update a file. |
| |
| ==== Remedy |
| |
| Jetty provides a configuration switch in the `webdefault.xml` file for the DefaultServlet that enables or disables the use of memory-mapped files. |
| If you are running on Windows and are having file-locking problems, you should set this switch to disable memory-mapped file buffers. |
| |
| The default `webdefault.xml` file is found in the jetty distribution under the `etc/` directory or in the `jetty-webapp-${VERSION}.jar` artifact at `org/eclipse/jetty/webapp/webdefault.xml`. |
| Edit the file in the distribution or extract it to a convenient disk location and edit it to change `useFileMappedBuffer` to false. |
| The easiest option is to simply edit the default file contained in the jetty distribution itself. |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <init-param> |
| <param-name>useFileMappedBuffer</param-name> |
| <param-value>true</param-value> <!-- change to false --> |
| </init-param> |
| |
| |
| ---- |
| |
| Make sure to apply your custom `webdefault.xml` file to all of your webapps. |
| You can do that by changing the configuration of the Deployment Manager in `etc/jetty-deploy.xml`. |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <Call id="webappprovider" name="addAppProvider"> |
| <Arg> |
| <New class="org.eclipse.jetty.deploy.providers.WebAppProvider"> |
| . |
| . |
| <!-- this should be the new custom webdefault.xml or change should be made in this file --> |
| <Set name="defaultsDescriptor"><Property name="jetty.home" default="." />/etc/webdefault.xml</Set> |
| <Set name="scanInterval">1</Set> |
| <Set name="extractWars">true</Set> |
| . |
| . |
| </New> |
| </Arg> |
| </Call> |
| |
| |
| ---- |
| |
| Alternatively, if you have individually configured your webapps with context xml files, you need to call the `WebAppContext.setDefaultsDescriptor(String path)` method: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <New id="myWebAppContext" class="org.eclipse.jetty.webapp.WebAppContext"> |
| <Set name="contextPath">/</Set> |
| <Set name="war">./webapps/fredapp</Set> |
| <Set name="defaultsDescriptor">/home/fred/jetty/mywebdefaults.xml</Set> |
| . |
| . |
| </New> |
| |
| |
| ---- |
| |
| Instead, you could redefine the DefaultServlet in your web.xml file, making sure to set useFileMappedBuffer to false: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <web-app ...> |
| ... |
| <servlet> |
| <servlet-name>Default</servlet-name> |
| <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class> |
| <init-param> |
| <param-name>useFileMappedBuffer</param-name> |
| <param-value>false</param-value> |
| </init-param> |
| <load-on-startup>0</load-on-startup> |
| </servlet> |
| ... |
| </web-app> |
| |
| |
| ---- |
| |
| ==== Alternate Remedy |
| |
| You can force a `WebAppContext` to always copy a web app directory on deployment. |
| The base directory of your web app (ie the root directory where your static content exists) will be copied to the link:#ref-temporary-directories[temp directory]. |
| Configure this in an xml file like so: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <New id="myWebAppContext" class="org.eclipse.jetty.webapp.WebAppContext"> |
| <Set name="contextPath">/</Set> |
| <Set name="war">./webapps/fredapp</Set> |
| <Set name="copyWebDir">true</Set> |
| . |
| . |
| </New> |
| |
| ---- |
| |
| ____ |
| [NOTE] |
| Be careful with this option when using an explicitly setlink:#ref-temp-directories[temp directory] name - as the name of the temp directory will not unique across redeployments, copying the static content into the same directory name each time may not avoid the locking problem. |
| ____ |