logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ralph Goers <ralph.go...@dslextreme.com>
Subject Re: Odd problem starting program with log4j2 on Windows
Date Fri, 06 Jul 2018 04:11:39 GMT
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.goers@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.popma@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 <garydgregory@gmail.com> wrote:
>>> 
>>> 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
>>>> 
>>>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
>> For additional commands, e-mail: log4j-user-help@logging.apache.org
>> 
>> 
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Mime
View raw message