I found that the problem can be reproduced with this: new File(“file:C:\\temp\\some.file”).toURI()
If you print the above it shows: file:/C:/my/current/directory/file:C:/temp/some.file So, the configuration should not prefix the path with “file:”, but with “file:/“ (slash after the colon). (Shameless plug) Every java main() method deserves http://picocli.info > On Jul 6, 2018, at 10:52, Gary Gregory <garydgreg...@gmail.com> wrote: > > Can't URL contain commas? > > Gary > >> On Thu, Jul 5, 2018, 18:11 Ralph Goers <ralph.go...@dslextreme.com> wrote: >> >> Here is what Log4j does: >> >> If the property is specified first see if it contains any commas, if so >> then there will be multiple configuration files, which essentially does >> what follows for each file. If not then try to convert it to a URI using >> the following code: >> >> public static URI toURI(final String path) { >> try { >> // Resolves absolute URI >> return new URI(path); >> } catch (final URISyntaxException e) { >> // A file path or a Apache Commons VFS URL might contain blanks. >> // A file path may start with a driver letter >> try { >> final URL url = new URL(path); >> return new URI(url.getProtocol(), url.getHost(), >> url.getPath(), null); >> } catch (MalformedURLException | URISyntaxException nestedEx) { >> return new File(path).toURI(); >> } >> } >> } >> >> The URI is then converted to a ConfigurationSource using: >> public static ConfigurationSource fromUri(final URI configLocation) { >> final File configFile = FileUtils.fileFromUri(configLocation); >> if (configFile != null && configFile.exists() && configFile.canRead()) >> { >> try { >> return new ConfigurationSource(new >> FileInputStream(configFile), configFile); >> } catch (final FileNotFoundException ex) { >> ConfigurationFactory.LOGGER.error("Cannot locate file {}", >> configLocation.getPath(), ex); >> } >> } >> if (ConfigurationFactory.isClassLoaderUri(configLocation)) { >> final ClassLoader loader = >> LoaderUtil.getThreadContextClassLoader(); >> final String path = >> ConfigurationFactory.extractClassLoaderUriPath(configLocation); >> final ConfigurationSource source = fromResource(path, loader); >> if (source != null) { >> return source; >> } >> } >> if (!configLocation.isAbsolute()) { // LOG4J2-704 avoid confusing >> error message thrown by uri.toURL() >> ConfigurationFactory.LOGGER.error("File not found in file system >> or classpath: {}", configLocation.toString()); >> return null; >> } >> try { >> return new >> ConfigurationSource(configLocation.toURL().openStream(), >> configLocation.toURL()); >> } catch (final MalformedURLException ex) { >> ConfigurationFactory.LOGGER.error("Invalid URL {}", >> configLocation.toString(), ex); >> } catch (final Exception ex) { >> ConfigurationFactory.LOGGER.error("Unable to access {}", >> configLocation.toString(), ex); >> } >> return null; >> } >> I should point out that the stack trace log you are seeing is from the >> above code failing. If any of the above doesn’t work we then try to create >> a ConfigurationSource using the following code where config is the value of >> the property and loader is the ThreadContextClassLoader. So even with the >> error that is shown it is still possible that the file might be found. >> >> protected ConfigurationSource getInputFromString(final String config, >> final ClassLoader loader) { >> try { >> final URL url = new URL(config); >> return new ConfigurationSource(url.openStream(), >> FileUtils.fileFromUri(url.toURI())); >> } catch (final Exception ex) { >> final ConfigurationSource source = >> ConfigurationSource.fromResource(config, loader); >> if (source == null) { >> try { >> final File file = new File(config); >> return new ConfigurationSource(new FileInputStream(file), >> file); >> } catch (final FileNotFoundException fnfe) { >> // Ignore the exception >> LOGGER.catching(Level.DEBUG, fnfe); >> } >> } >> return source; >> } >> } >> ConfigurationSource.fromResource() tries to locate the resource using >> ClassLoader.getResource() and then constructs a ConfgurationSource if it >> can find it. And if all else fails we just pass the string to the File >> constructor and hope for the best. >> As you can see we aren’t really manipulating the input string that was >> provided to us, but we are trying any way we can to convert it into some >> sort of file we can access. If you see something missing in this logic >> please let us know. >> >> Ralph >> >> >> >> >> >>> On Jul 5, 2018, at 1:59 PM, Shawn Heisey <apa...@elyograg.org> wrote: >>> >>> On 7/5/2018 11:38 AM, Ralph Goers wrote: >>>> I have updated the issue you referenced. From what I can tell this is >> not an issue in Log4j. It is an issue with the way file urls work. >>> >>> Thanks for your attention. >>> >>> The startup script included with Solr versions before 7.4 (using log4j >>> 1.2.x) also did not have // in the file: URI for the log4j.properties >>> file, and it works on both Linux and Windows. >>> >>> Something else I found in the RFC you linked: >>> >>> The syntax given in Section 2 makes the entire authority component, >>> including the double slashes "//", optional. >>> >>> Reading section 2, I didn't actually see that stated. Maybe it's >>> something clarified by one of the other referenced RFCs. But if we take >>> that statement at face value, it seems to be saying that a URI without >>> // should work. It *does* work on Linux. On Windows, this: >>> >>> file:C:\path\to\stuff\log4j2.xml >>> >>> gets translated into this: >>> >>> file:/$CWD/file:C:/path/to/stuff/log4j2.xml >>> >>> Where $CWD is the current working directory. Even the "extra" URI added >>> as a prefix doesn't have the // in it. If instead we use the following, >>> it works as expected: >>> >>> file://C:\path\to\stuff\log4j2.xml >>> >>> If you're sure that there's nothing in log4j code that would result in >>> the strange location, I'd be willing to accept that this problem is >>> caused by Java or the OS and not log4j. The fact that this doesn't >>> happen on Linux is even more reason to believe that. I don't know how >>> likely it is that log4j contains code that behaves differently based on >>> detected OS ... but I strongly believe that you'd want to avoid that if >>> possible. >>> >>> I believe that we can safely add // to Solr's command script to solve >>> this issue for our users, because the value should always be a full >>> absolute path. >>> >>> But I would like to pursue the remaining question: When the RFC is >>> fully and correctly evaluated, is a "file:" URI without "//" considered >>> valid? If not, then that ends the discussion. If it is considered >>> valid, then there's another question: Is it Java, log4j, or Windows that >>> is causing the problem we've seen? >>> >>> Another question: What is the stance of the project on whether non-URI >>> syntax for the log4j.configurationFile system property will be supported >>> long-term? I can remember running into a problem with logging >>> configuration in the past (I *think* it was log4j 1.x, but it MIGHT have >>> been java.util.logging) where the configuration wasn't found until I >>> added "file:" to turn it into a URI. I did not use // in the URI. This >>> is a line from the init script I wrote for Solr 4.x versions (when Solr >>> did not include a startup script): >>> >>> LOG_OPTS="-Dlog4j.configuration=file:etc/log4j.properties" >>> >>> Thanks, >>> Shawn >>> >>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org >>> For additional commands, e-mail: log4j-user-h...@logging.apache.org >> >> --------------------------------------------------------------------- To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-user-h...@logging.apache.org