I agree.

Nick

On Jan 29, 2014, at 5:09 PM, Paul Benedict wrote:

> I would like to propose not doing anything on this subject until there is a 
> request from the community. It's probably way too easy to over-engineer and 
> devise solutions to problems that a small percentage (or zero?) of the users 
> will need. I am all for ingenuity and passion, but after GA occurs and 
> there's no experience with custom levels directly, we might get a better idea 
> what the "right" answer is. 
> 
> So slate this for 2.x in JIRA and let's get to GA.
> 
> 
> On Wed, Jan 29, 2014 at 4:53 PM, Matt Sicker <boa...@gmail.com> wrote:
> Annotation processing is beyond over-engineered, yet it still lacks some of 
> the neat features from runtime annotation "processing". I've been meaning to 
> look more into it as it might be useful for injecting Loggers using 
> annotations.
> 
> 
> On 29 January 2014 07:46, Remko Popma <remko.po...@gmail.com> wrote:
> 
> 
> On Wednesday, January 29, 2014, Nick Williams <nicho...@nicholaswilliams.net> 
> wrote:
> 
> On Jan 28, 2014, at 5:43 PM, Remko Popma wrote:
> 
>> I would really like everyone's feedback on this. I have two questions:
>> 
>> 1. Does this fulfill everyone's requirements?
>> Another way of asking this is: would you use this in your own projects? (If 
>> not, why not?)
> 
> Personally, no. I don't like the code generation for IDE integration issues. 
> I'd prefer an interface I wrote.
> 
> I'm not sure what you mean by IDE integration issues, but let's not lose 
> sight of why we are doing this in the first place: we want to provide 
> convenience methods to make custom levels as easy to use as built-in levels. 
> I'm beginning to feel that we are adding additional requirements on top of 
> this that make it difficult to achieve our original goal...
> 
> 
>> 2. What do you think of this approach?
>> Obviously code generation has drawbacks. For one thing, IDE refactoring 
>> tools don't work and API changes don't cause compile errors in the generator 
>> itself, only in the generated code. (I plan to add a JUnit test that 
>> generates a custom logger, compiles it and executes the custom logging 
>> methods so we can at least catch issues during the build.)
>> The advantage is that it is open-ended and can deal with any custom level 
>> users can dream up. 
>> 
>> Is this trade-off acceptable?
>> Are there other ways to solve this?
> 
> Also IMO, I would tend to steer away from only generating a concrete class. 
> The interface and implementation should be separate. Imagine a Log4j fixing a 
> bug in the generation code and releasing 2.0.1 or whatever. Now the user has 
> a generated implementation, so they can't /just/ upgrade their Maven 
> dependency. They /also/ have to re-generate their code. That's a pain. 
> However, with the interface and implementation separate, the interface 
> probably doesn't have to change, and the implementation will change as soon 
> as they fire up their app with the latest Log4j.
> 
> Also, if you separate the interface and implementation, you can make the 
> generation of the interface optional. The user can /choose/ whether to 
> generate the interface or create the interface themselves. Then the 
> implementation generates at runtime.
> 
> My original intuition was also to start with a separate interface and 
> implementation but as I was thinking about "what is the simplest thing that 
> could possibly work?" I ended up with this design. Please don't dismiss this 
> solution just because it is based on a concrete class. 
> 
> Generating an implementation at runtime just seems so much more complex. It 
> involves inspecting the signature of every method on the interface to see 
> which Logger.log(Level, ...) method it should be mapped to. And what is there 
> is no match? We would need to throw an IllegalArgumentException at runtime. 
> This problem does not exist with the concrete class. 
> 
> I've taken a look at ASM (http://asm.ow2.org/) to generate byte code 
> on-the-fly but I have kind of given up on that idea. (If anyone else wants to 
> take this on please feel free but it seems the result may be fragile and 
> difficult to maintain.)
> 
> The alternative is probably annotation processing. This is interesting stuff 
> and I look forward to taking a closer look into this in the next week or so. 
> But just looking at the API, "simple" is not the word that comes to mind. :-) 
> Also be aware that generating an implementation class at runtime would 
> require users to have tools.jar in the classpath so we can compile the 
> generated implementation class source code at runtime. The concrete class 
> does not need additional jars. 
> 
> So there's a bunch of trade-offs here. I'd like to understand annotation 
> processing a bit better first, but I still think the simplicity of the 
> concrete class has a lot of appeal. 
> 
> 
> 
> Nick
> 
>> 
>> Remko
>> 
>> On Tuesday, January 28, 2014, Remko Popma <remko.po...@gmail.com> wrote:
>> I created https://issues.apache.org/jira/browse/LOG4J2-519 for this. 
>> Feedback welcome. 
>> 
>> On Tuesday, January 28, 2014, Remko Popma <remko.po...@gmail.com> wrote:
>> I've started to work on implementing a source code generator along the lines 
>> described below.
>> 
>> Does anyone disagree with this approach?
>> 
>> I was thinking to name the tools Generate$ExtendedLogger and 
>> Generate$CustomLogger and put the Generate class in the log4j-api project 
>> under org.apache.logging.log4j.util or create a new package called 
>> org.apache.logging.log4j.experimental.
>> 
>> Thoughts?
>> 
>> On Tuesday, January 28, 2014, Remko Popma <remko.po...@gmail.com> wrote:
>> More thoughts on CustomLogger/ExtendedLogger source code generation:
>> 
>> Perhaps I was overcomplicating things...
>> Why don't we generate source for a concrete class instead of an 
>> interface+implementation?
>> 
>> If users want to /extend/ Logger, this class would extend 
>> AbstractLoggerWrapper (which has the standard debug(), info(), warn(), ... 
>> methods).
>> 
>> If users want to hide the standard methods, the generated class would simply 
>> not extend AbstractLoggerWrapper, so the only public methods would be the 
>> generated methods for the custom log levels.
>> 
>> This allows users to generate both extended loggers (with extra methods) and 
>> custom domain specific Loggers (like a logger that only has defcon1(), 
>> defcon2(), defcon3() methods).
>> 
> 
> 
> 
> -- 
> Matt Sicker <boa...@gmail.com>
> 
> 
> 
> -- 
> Cheers,
> Paul

Reply via email to