logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Remko Popma <remko.po...@gmail.com>
Subject Re: Odd problem starting program with log4j2 on Windows
Date Fri, 06 Jul 2018 04:23:24 GMT
I’m not sure. The weird behavior can be expected, given that the specified string is neither
a correct path, nor a correct URL:

new File(“file:C:\\temp\\some.file”).toURI()

It’s simply invalid input. 

Should log4j attempt to handle this invalid input?

(Shameless plug) Every java main() method deserves http://picocli.info

> On Jul 6, 2018, at 13:11, Ralph Goers <ralph.goers@dslextreme.com> wrote:
> 
> 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
> 

---------------------------------------------------------------------
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