Issues
- Docker Desktop 2.2.x Windows filesharing breaks LuceeLDEV-2648Resolved issue: LDEV-2648
- Regression in struct implementation causing stack overflowLDEV-2608Resolved issue: LDEV-2608Michael Offner
- lucee.runtime.exp.NativeException: java.lang.StackOverflowErrorLDEV-2479Resolved issue: LDEV-2479Michael Offner
- include localisation masks in GetLocaleInfo()LDEV-2315Resolved issue: LDEV-2315Pothys - MitrahSoft
Docker Desktop 2.2.x Windows filesharing breaks Lucee
Description
Environment
Windows 10 & Docker Desktop 2.2 (gRPC FUSE filesharing)
Details
Details
Assignee
Reporter
Priority
New Issue warning screen
Before you create a new Issue, please post to the mailing list first https://dev.lucee.org
Once the issue has been verified, one of the Lucee team will ask you to file an issue
Affects versions
Activity
Samuel W. Knowlton3 February 2020 at 19:06
This ticket can be closed - as the github issue linked in the comments indicates, it’s not anything Lucee’s doing; it impacts ACF as well, and it’s not clear that Lucee could ‘fix’ it even if it cared to. Docker already has a fix in testing.
Samuel W. Knowlton22 January 2020 at 20:45
@John Berquist You’re exactly right - it’s not a problem with Lucee in the sense that anything is wrong with Lucee. Rather, it’s a problem affecting Lucee that chewed up half of yesterday and all of today for me, so I figured I’d put what I had up here.
It’s definitely the case that the new filesharing stuff has some problems, and since it only impacts Windows bind mounts, I doubt it’s worth any Lucee development time – Docker will patch it soon enough and until they do, I’m just updating Windows to use the WSL2 implementation anyway!
John Berquist22 January 2020 at 20:39
For what it is worth, I don’t think this is a Lucee problem, at least not directly. If you look at the stack trace above, you can see it was in the following method: lucee.runtime.PageSourceImpl.loadPage(PageSourceImpl.java:210)
If you check that method in the source, it calls the loadPhysical()
method in the same file. That method has the following check:
long srcLastModified = srcFile.lastModified();
if (srcLastModified == 0L) return null;
So the component load will fail if the source file lastModified()
returns `0`. Lucee uses a `FileResource` that extends java.io.File
, which does the actual last modified check. So you can do something like the following (file I got an error for) in the Application.cfc
onRequestStart()
:
f = createObject('java', 'java.io.File').init('/app/coldbox/system/logging/Logger.cfc');
writeDump(f.lastModified());
abort;
The reported last modified will (in some cases) be 0. And when Lucee sees that, it returns null. Reporting a 0 last modified time looks a lot like this issue (reported today): https://github.com/docker/for-win/issues/5543 In fact, there are a bunch of issues regarding the new file sharing mechanism, so it is clearly still buggy.
Samuel W. Knowlton22 January 2020 at 16:44
I tested this both with our apps and a vanilla Coldbox ‘advanced’ template, with symlinks and without.
Windows uses SMB for Docker filesharing prior to Desktop 2.2. It can handle symlinks (and we have used them in the past) but I tested an app template just to eliminate our code as a culprit.
Brad Wood22 January 2020 at 16:39
@Samuel W. Knowlton Out of curiosity, is some sort of symlink being used behind the scenes?
This problem is limited to Windows environments but occurs whether you are using the native Lucee Docker images or Commandbox with Docker Desktop 2.2.x (or 2.1.7 on the Edge channel). This is the change in Docker that triggers the problem:
https://www.infoq.com/news/2019/12/docker-desktop-windows-fuse/
https://www.docker.com/blog/deep-dive-into-new-docker-desktop-filesharing-implementation/
If you have a folder on the host that you are bind-mounting into the container (into /app for Commandbox or /var/www for Lucee), the first request to the container will succeed but all subsequent requests throw an exception: lucee.runtime.exp.MissingIncludeException: Page /Application.cfc /app/Application.cfc not found
This does not occur if you make a single .cfm file in a folder without Application.cfc. It appears to be related to Lucee trying to include another file. It is not affected by changing the Lucee admin settings for 'inspect always.'
We have tried every variation of bind mount that we can think of, and using docker run instead of `docker-compose` – no difference.
You can log in to the container and see all the files with no problem. There do not appear to be any permission issues. It does not matter if you are using JRE8 or JRE11.
The other 4-5 containers in our dev stack are working fine - even a couple others with bind mounts.
Stack trace:
[ERROR] runwar.context: lucee.runtime.exp.MissingIncludeException: Page /Application.cfc [/app/Application.cfc] not found at lucee.runtime.PageSourceImpl.loadPage(PageSourceImpl.java:210) at lucee.runtime.component.ComponentLoader.loadComponent(ComponentLoader.java:375) at lucee.runtime.listener.ModernAppListener._onRequest(ModernAppListener.java:113) at lucee.runtime.listener.ModernAppListener.onRequest(ModernAppListener.java:104) at lucee.runtime.PageContextImpl.execute(PageContextImpl.java:2409) at lucee.runtime.PageContextImpl._execute(PageContextImpl.java:2399) at lucee.runtime.PageContextImpl.executeCFML(PageContextImpl.java:2374) at lucee.runtime.engine.Request.exe(Request.java:43) at lucee.runtime.engine.CFMLEngineImpl._service(CFMLEngineImpl.java:1109) at lucee.runtime.engine.CFMLEngineImpl.serviceCFML(CFMLEngineImpl.java:1055) at lucee.loader.engine.CFMLEngineWrapper.serviceCFML(CFMLEngineWrapper.java:97) at lucee.loader.servlet.CFMLServlet.service(CFMLServlet.java:51) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) at org.cfmlprojects.regexpathinfofilter.RegexPathInfoFilter.doFilter(RegexPathInfoFilter.java:47) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176) at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145) at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92) at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:389) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.intergral.fusionreactor.j2ee.filterchain.WrappedFilterChain.doFilter(WrappedFilterChain.java:134) at com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doNext(FusionReactorRequestHandler.java:764) at com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doHttpServletRequest(FusionReactorRequestHandler.java:344) at com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doFusionRequest(FusionReactorRequestHandler.java:207) at com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.handle(FusionReactorRequestHandler.java:801) at com.intergral.fusionreactor.j2ee.filter.FusionReactorCoreFilter.doFilter(FusionReactorCoreFilter.java:36) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.intergral.fusionreactor.j2ee.filterchain.WrappedFilterChain.doFilter(WrappedFilterChain.java:71) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.intergral.fusionreactor.agent.filter.FusionReactorStaticFilter.doFilter(FusionReactorStaticFilter.java:54) at com.intergral.fusionreactor.agent.pointcuts.NewFilterChainPointCut$1.invoke(NewFilterChainPointCut.java:42) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:64) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:336) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)