logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gary Gregory <garydgreg...@gmail.com>
Subject Re: Odd problem starting program with log4j2 on Windows
Date Fri, 06 Jul 2018 01:52:38 GMT
Can't URL contain commas?

Gary

On Thu, Jul 5, 2018, 18:11 Ralph Goers <ralph.goers@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 <apache@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-unsubscribe@logging.apache.org
> > For additional commands, e-mail: log4j-user-help@logging.apache.org
> >
> >
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message