本文原英文地址:http://www.eclipse.org/jetty/documentation/9.3.0.v20150612/troubleshooting-locked-files-on-windows.html#d0e26059
在jetty容器内,对于静态文件,会采用内存缓存的实现方式,如采用buteBuffer的方式来进行缓存。如果使用NIO连接器(默认情况),jetty就会采用文件映射(filemapper)的方式。但是这个方式在windows下会存在一个问题,即使用文件内存映射会导致这个文件被进程锁住,其它进程就不能但修改或者替换这个文件了。解决这个问题的一个方法就会停掉jetty,但这种方式显示不太靠谱。
jetty提供了一个开关标记来开启或者禁止内存映射,在类DefaultServlet中有一个属性useFileMappedBuffer,此属性值默认为false,并且在配置文件webdefault.xml中进行配置。
默认的配置文件存储在jar包jetty-webapp-${version}.jar中的org/eclipse/jetty/webapp/webdefault.xml,还有一份存储在jetty-home/etc/目录中。两者的区别在于,后者由jetty运行时配置文件中默认使用。前者由在代码中WebAppContext默认使用(没有配置值的情况下).最简单的作法就是修改这个配置文件,如下所示:
<init-param> <param-name>useFileMappedBuffer</param-name> <param-value>true</param-value> <!-- change to false --> </init-param>
上面的配置文件的修改的前提在于保证jetty是使用了这个配置文件的,在etc/jetty-deploy.xml中,jetty会默认值此配置文件来配置相应的webAppContext属性,配置代码如下所示:
<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>
如果我们在自定义的配置文件,那么也可以通过复制一份webdefault.xml文件,然后在自定义的context.xml中,指定相对应的配置描述符路径信息,如下所示:
<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>
在这个复制的webdefault配置文件当中,我们就可以修改相应的配置属性,将其修改为false,如下参考所示:
<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>
备注:
在使用idea中的jetty插件时,idea会提供一个新的context.xml文件,然后使用默认的webContext配置,因此相应的配置属性读取于jar内的webdefault.xml文件。因此,想要在idea中解决此问题,需要将相应的jar(etty-webapp-${version}.jar)解压开,修改相应的配置文件 ,再重新打包回jar中,通过替换jar的方式才能解决此问题。修改etc配置目录下的文件无效.
原英文全文如下:
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.
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.
<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.
<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:
<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:
<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>
转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/201510130001.html