[
https://issues.apache.org/jira/browse/LOG4J2-952?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14695342#comment-14695342
]
Bart S. commented on LOG4J2-952:
--------------------------------
A typical builder paradigm is that there is a fixed _Context_ and the context
doesn't change from one method invocation to the next.
Normally any Builder returns the same Builder from any of its methods, as what
you called the methods on.
So the relationship holds that:
Builder b = builder.doSomething() ----> b == builder
In fluent API speak this is called the context.
If half of your methods return actual objects and the other half inserts those
objects into the planned configuration (thus honouring the builder thing) then
I guess technically there might not be an amazing issue (as long as the
configuration object already exists and you can pass it into the new created
objects) (which is in itself an issue) (you can't have flee floating objects,
they have to be attached to a configuration right from the get go the way it
currently is, I believe)....
But the only advantage is a bit of type checking. You won't be creating a new
Log4J configuration every day I hope. Unless you have a 1000 line
configuration, even considering it would be possible with the builder, the
amount of "debugging" you MIGHT need to do AFTER the runtime engine tells you
there has been a mistake is just very minimal.
There are just not any practical advantages to having the real objects in your
hands.
At WORST your program might display some errors because you have made a typing
mistake, the exact same thing as when you'd use an XML or other file!!!!!.
Now if some method returned a specific builder instance FOR one of those
objects and you were allowed to manipulate it own your own before sending it
back into function (or being registered at the start) that might not be so bad:
*In that case you'd have the Configuration.Builder store a collection of
Builder objects for the various classes. It would than transform those builder
objects into actual objects before implanting them into the Configuration it is
making.*
However I think the two stage approach we have here is much prettier even if I
don't agree with all the Maps, (seems too easy) and more powerful. Also I
believe Maps are expensive objects, but that might be beside the point.
The problem with the current situation is precisely that you need a large
number of imports to do anything:
{code}
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.LoggerConfig;
{code}
If you created an abstraction interface that would still require all those
imports (because you'd have to store the references yourself) that would
perfectly devoid the whole sense of creating a fluid API (fluent API) to do
things.
So I think then the main advantage of having a Builder would be gone. A Builder
should not give back weird objects, it should stay a Builder. Now, how
important that is is up to debate.
But I would at this point stick to the simple interface I have / we have
described. Just use string literals, why not. The only alternative is to create
something fluent that ensures you don't have to _keep the references around_ as
you pass one object to the next. Then you'd probably want to use sub-builder
classes (such as SyslogOptions.Builder) that either did "Register-in-Front" as
the prettiest solution, or "Finalize-with-Build" and pass the object to the
system, as the ugliest. Like I have indicated.
Personally I don't see why you'd be interested in having a ConfigurationBuilder
if the amount of work required to use it would still be 70% of what you had
before?.
> FAQ: How do I configure log4j2 programmatically in code without a
> configuration file?
> -------------------------------------------------------------------------------------
>
> Key: LOG4J2-952
> URL: https://issues.apache.org/jira/browse/LOG4J2-952
> Project: Log4j 2
> Issue Type: Bug
> Components: API, Configurators, Documentation
> Affects Versions: 2.1
> Reporter: Joe Merten
>
> I found [this
> link|http://logging.apache.org/log4j/2.x/faq.html#config_from_code] which
> said:
> {quote}
> You could use the static method #initialize(String contextName, ClassLoader
> loader, String configLocation) in
> org.apache.logging.log4j.core.config.Configurator. (You can pass null for the
> class loader.) Be aware that this class is not part of the public API so your
> code may break with any minor release.
> {quote}
> This documentation is unclear because it points to a member function which
> needs a filename {{configLocation}} where as the topic is »without a
> configuration file«.
> It shoud rather point to the member function
> {{org.apache.logging.log4j.core.config.Configurator.initialize(ClassLoader
> loader, ConfigurationSource source)}}.
> Example:
> {code:java}
> import org.apache.logging.log4j.core.config.ConfigurationSource;
> import org.apache.logging.log4j.core.config.Configurator;
> final String hardCodedXmlConfig =
> "<?xml version='1.0' encoding='UTF-8'?>\n" +
> "<Configuration status='INFO'>\n" +
> " <Appenders>\n" +
> " <Console name='Console' target='SYSTEM_OUT'>\n" +
> " <PatternLayout pattern='%d{HH:mm:ss.SSS} [%t] %-5level
> %logger{36} - %msg%n'/>\n" +
> " </Console>\n" +
> " </Appenders>\n" +
> " <Loggers>\n" +
> " <Root level='debug'>\n" +
> " <AppenderRef ref='Console'/>\n" +
> " </Root>\n" +
> " </Loggers>\n" +
> "</Configuration>\n";
> try {
> Configurator.initialize(null, new ConfigurationSource(new
> ByteArrayInputStream(hardCodedXmlConfig.getBytes())));
> } catch (IOException e) {
> e.printStackTrace();
> }
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]