I suppose we could look for that and fix it, but that would mean having Windows specific code.
Ralph > On Jul 5, 2018, at 9:10 PM, Ralph Goers <ralph.go...@dslextreme.com> wrote: > > So that is some weirdness with Java itself, and only on Windows. > > Ralph > >> On Jul 5, 2018, at 7:34 PM, Remko Popma <remko.po...@gmail.com> wrote: >> >> 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 >> >> > --------------------------------------------------------------------- To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-user-h...@logging.apache.org