I do have some trouble understanding the log4j2 wrapper usage.
If you follow this link you will find attached an example using the AbstractLoggerWrapper. I just copied the following peace of code.
public class Log4j2Logger extends AbstractLogger
{
private static final String FQCN = AbstractLogger.class.getName();
private AbstractLoggerWrapper logImpl;
public Log4j2Logger(String name, String prefix, String logId, String instanceId)
{
super(name, prefix, logId, instanceId);
final AbstractLogger logger = (AbstractLogger) LogManager.getLogger(name);
this.logImpl = new AbstractLoggerWrapper(logger, name);
}
....
#Override
public void log(String message, LogLevel level)
{
logImpl.log(null, FQCN, toImplLevel(level), new SimpleMessage(createMessage(message)), null);
}
....
}
I don't understand the reason for subclassing AbstractLogger and intern using the AbstractLoggerWrapper. I actually could just remove the extend from the Log4j2Logger and encapsulate the AbstractLoggerWrapper. Do you see any reason of doing it like in the code snipped above?
Is there any way to subclass the AbstractLogger (like preferred) and just use it without the wrapper? And create it like a strategy pattern? e.g.,
LogManager.getLogger( class.getName(), Log4j2Logger.class )
Maybe this is what they tried to explain in the extending section and I don't understand it, yet. Somebody any idea how to do it?
Sincerely
Christian
Update: I missed to say, the reason why I am using the wrapper is because of an existing projekt with log4j (1.2) with a wrapper.
If you look at the documentation for AbstractLoggerWrapper:
Wrapper class that exposes the protected AbstractLogger methods to
support wrapped loggers.
You will see a clear indication as to why it is done the way Apache does it. If you instead decide to ignore the contract of the interface and go your own way, you are essentially saying
"I don't care how the library does things, I know better"
As such, you are taking on a great deal of risk, instead of using the general solution that has been provided. I sincerely doubt that you have such an esoteric environment that the library could would be insufficient.
To recap, follow the contract laid out by the library documentation.
Related
i have a little kont in my brain about structuring our code. We have a REST Backend based on SpringBoot. To handle requests regarding to security checks we use HandlerInterceptors. In some specific cases we need a specific interceptor and not our default one. The default one is registered in a 3rd party lib that no one can forget it. But i want all coders to think about this specific interceptor.
Actually, i just said it to them to achieve this.
Here's my question: Is there an option to create required (or necessary) interfaces which must be implemented? This would be a way to provide our security code by lib and to have the security that every coder implemented our specific interface (also if he just does nothing with it).
pseudo code:
public interface thinkForIt(){
Object SecBean specificSecBean;
public void methodToThinkOn();
}
public SecImpl implements thinkForIt(){
#Override
public void methodToThinkOn(){
return null; // i thought about it but i do not need to do anyting!
}
If the interface thinkForIt would have any annotations like #required, users could get warning or error if they did not implement it...
Looking for a solution and thanks for your comments in advance!
Your overall design is questionable; you are reinventing security code, which is always a red flag. Use Spring Security instead.
However, there's a simple way to ensure that "some bean of type Foo" has been registered with the context:
#Component
#RequiredArgsConstructor
public class ContextConfigurationVerifier {
final Foo required;
}
Say I follow the Single Responsibility Principle and I have the following classes.
public class Extractor {
public Container extract(List<Container> list) {
... some extraction
}
}
public class Converter {
public String convert(Container container) {
... some conversion
}
}
As you can see it's following the principle and all the names of the classes/methods tell what they do. Now I have another class that has a method like this.
public class SomeClass {
private Extractor extractor = new Extractor();
private Converter converter = new Converter();
private Queue queue = new Queue();
public void someMethod(List<Container> list) {
Container tmp = extractor.extract(list);
String result = converter.convert(tmp);
queue.add(result);
}
}
As you can see the "someMethod"-Method does call extract, convert and add. My question is now, how do you call such a class/method? It's not actually extracting, converting or adding but it's calling those?
If you name the method after its responsibility what would that be?
Well since you seem to add to a queue and you don't return anything I'd call it addToQueue. The fact that you convert + extract is implementation detail that I don't think needs to be exposed.
What about processAndQueueMessage?
Also (not related), you shouldn't create (using new) the Extractor and Converter in your SomeClass, you should rather inject them (at construction or in setters), and use interfaces to them. That will make it easier to test, and reduce coupling between implementations.
// Assuming Converter and Extractor are interfaces to the actual implementations
public class SomeClass {
private final Extractor extractor ;
private final Converter converter;
private Queue queue = new Queue();
public SomeClass(Extractor extractor, Converter converter) {
this.converter = converter;
this.extractor = extractor;
}
public void someMethod(List<Container> list) {
Container tmp = extractor.extract(list);
String result = converter.convert(tmp);
queue.add(result);
}
}
And you create it using:
final SomeClass myProcessor = new SomeClass(new MyExtractorImplementation(), new MyConverterImplementation());
(Or use a DI container, like Spring or Pico)
What you do is think about the composite meaning of the sequence of method calls, turn that into a concise verb or verb phrase and use that as the name. If you can't come up with a concise name then you could use a generic / neutral name (like "process") or use something completely bogus (like "sploddify").
If you want the name to be really generic, I'd go with addToQueue() or populateQueue() since getting something into that object seems to be the point of the method.
But really at that level I'd call it by what business logic it's trying to accomplish, in which case the name really depends on what it's being used for.
If you can't come up with a good name, it is an indication that your procedural abstraction is rather arbitrary / artificial, and a possible hint that there might be a better way to do it. Or maybe not.
Sounds like some kind of builder class. You get data in one format, convert it and then create some kind of output format. So how about "SomethingSomethingBuilder"?
I'm assuming someone downvoted me because I forgot to provide a good name for the method. Sorry about that.
So this method adds incrementally data into your builder class. I would call it, "Add", "AddData" or "Push" (I'd probably go with push because that has very similar meaning in many standard classes).
Alternative to "Builder" could potentially be "SomeKindOfCreator". Obviously you would name it based on whatever it is your class is actually creating.
In the real world what do people use this for (to solve what types of problems)? Can I see some example code of these working together? All I can find is code about cats and dogs speaking or people drinking milk or coffee...
Do people really implement polymorphism with interfaces? What for?
Sure,
Below is concrete example of the "Observer" pattern, using classes and interfaces to accomplish polymorphic behavior in a logger system:
interface ILogger{
public void handleEvent (String event);
}
class FileLogger implements ILogger{
public void handleEvent (String event){
//write to file
}
}
class ConsoleLogger implements ILogger{
public void handleEvent (String event){
System.out.println( event );
}
}
class Log {
public void registerLogger (ILogger logger){
listeners.add(logger);
}
public void log (String event){
foreach (ILogger logger in listeners){
logger.handleEvent(event); //pass the log string to both ConsoleLogger and FileLogger!
}
}
private ArrayList<ILogger> listeners;
}
Then, you could use it as follows:
public static void main(String [] args){
Log myLog();
FileLogger myFile();
ConsoleLogger myConsole();
myLog.registerLogger( myFile );
myLog.registerLogger( myConsole );
myLog.log("Hello World!!");
myLog.log("Second log event!");
}
Hope this helps your understanding of interfaces and polymorphism.
Map<String,Person> peopleByName = new HashMap<String,Person>();
If, down the road, I decide the memory overhead of HashMap is too much, I can re-do this as a TreeMap, and live with the slightly more expensive lookup times
Map<String,Person> peopleByName = new TreeMap<String,Person>();
Because peopleByName is a Map, not a TreeMap or a HashMap, all my calls are guaranteed to work on either map regardless of implementation.
This is best illustrated with the following example
public class CatsAndDogsDrinkingMilkAndCoffee {
// what, no? :-(
}
interface Request {
Response execute();
}
interface Response {
String serialize();
}
class RequestProcessor {
void processRequest(Request r) {
logger.log("Request: " + r);
Response s = r.execute();
logger.log("Response: " + s);
connectionManager.write(r.serialize());
}
}
Say in this example, RequestProcesor doesn't need to know about implementations of Request and Response
Have a look at the code for Map/AbstractMap/HashMap as an example. You will find thousands of other examples in the JDK source which comes with the JDK (in src.zip)
imagine "somebody" designed a huge program, with lotsa code. suppose that "that somebody" used interfaces in the design of some controller logic. now you are hired to work with this code which youve never seen before. you are asked to design a new controller class. all you need to do now is to implement the interface and make all its methods work.
if that somebody had not used interfaces, then not only would you have to redesign the controller, but you would probably need to redesign potentially the whole project because there is very strong coupling between the controller class and the rest of the classes. this will take you months just to understand the code, not to mention the new set of bugs you would probably introduce..
Almost any Java application with GUI uses it (but of course not only GUI...). For example, look at the source of android VideoView (this is the first comes to my mind...)
Another suggestion I'd have for "the real world" is in using spring batch. If you have a commonly used report format that follows a pattern like "pull data, create report, send to recipients" you can create an interface for your reports that enforces this standard. In this sense it works like a "template" that all batch reports would follow.
A boring example, but it's something I faced in my first year...
Have you wondered how LINQ in .net works ? It's all about Interfaces and polymorphism.
You need to work on projects then you will come to know about all this.
How can I change what a method is doing in Java ?
I mean, I am trying to use annotations to make the following code
#Anno1(Argument = "Option1")
public class TestClass
{
#Anno2
public void test()
{
}
}
Into
public class TestClass
{
private static StaticReference z;
public void test()
{
z.invokeToAll();
}
}
This is a very simplified example of what I am trying to do. Anno1 will have many possible combinations, but this is not my problem so far. My problem is how to add code to method test()
I am looking for a more generic solution if possible. Eg. A way to add every kind of code in the method (not just a way to .invokeToAll())
So far I am using import javax.annotation.processing.*; and I have the following code, but I don't know how to go on from there
private void processMethodAnnotations(RoundEnvironment env)
{
for (Element e : env.getElementsAnnotatedWith(Anno2.class))
{
//If it is a valid annotation over a method
if (e.getKind() == ElementKind.METHOD)
{
//What to do here :S
}else
{
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,"Not a method!", e);
}
}
}
I have found something about Java Reflection but I have not found any source to help me with what I am doing.
Obviously I extends AbstractProcessor in my code
I have found this tutorial (http://www.zdnetasia.com/writing-and-processing-custom-annotations-part-3-39362483.htm) But this concerns creating a new class, not just changing a method. and the javax.lang.model.elements do not provide any way of editing that element (which in my case represents a Method).
I hope my question is clear and inline with the rules. If not please comment and I will clarify. Thanks.
Annotation processing is the wrong way to go for you, from Wikipedia:
When Java source code is compiled,
annotations can be processed by
compiler plug-ins called annotation
processors. Processors can produce
informational messages or create
additional Java source files or
resources, which in turn may be
compiled and processed, but annotation
processors cannot modify the annotated
code itself.
People suggested to you the right way - AOP. Specifically, you can use AspectJ. "Quick result" way is (if you use Eclipse):
Install AJDT (AspectJ Development Tools)
Create an AspectJ project and add there your classes and annotations
Create Aspect:
public aspect Processor {
private StaticReference z;
pointcut generic()
// intercept execution of method named test, annotated with #Anno1
// from any class type, annotated with #Anno2
: execution(#Anno2 * (#Anno1 *).test())
// method takes no arguments
&& args ();
// here you have written what you want the method to actually do
void around () : generic() {
z.invokeToAll();
}
}
now you can execute a test and you will see that it works ;) AJDT compiles code for you automatically, so do not need any manual work to do, hope that's what you called "magic" ;)
UPDATE:
if your code in the test() method depends on the Anno1 annotation value, then inside aspect you can get class annotation for which it is executed this way:
void around () : generic() {
Annotation[] classAnnotations = thisJoinPoint.getThis().getClass().getAnnotations();
String ArgumentValue = null;
for ( Annotation annotation : classAnnotations ) {
if ( annotation instanceof Anno1 ) {
ArgumentValue = ((Anno1) annotation).Argument();
break;
}
}
if ( ArgumentValue != null && ArgumentValue.equals("Option1")) {
z.invokeToAll();
}
}
where thisJoinPoint is a special reference variable.
UPDATE2:
if you want to add System.out.println( this ) in your aspect, you need to write there System.out.println( thisJoinPoint.getThis() ), just tested and it works. thisJoinPoint.getThis() returns you "this" but not exactly; in fact this is Object variable and if you want to get any propery you need either to cast or to use reflection. And thisJoinPoint.getThis() does not provide access to private properties.
Well, now seems that your question is answered, but if I missed anything, or you get additional question/problems with this way - feel free to ask ;)
It's perfectly possible to do what you ask, although there is a caveat: relying on private compiler APIs. Sounds scary, but it isn't really (compiler implementations tend to be stable).
There's a paper that explains the procedure: The Hacker's Guide to Javac.
Notably, this is used by Project Lombok to provide automatic getter/setter generation (amongst other things). The following article explains how it does it, basically re-iterating what is said the aforementioned paper.
Well, you might see if the following boilerplate code will be useful:
public void magic(Object bean, String[] args) throws Exception {
for (Method method : bean.getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(Anno2.class)) {
// Invoke the original method
method.invoke(bean, args);
// Invoke your 'z' method
StaticReference.invokeAll();
}
}
}
As an alternative your might employ aspect oriented programming, for instance you have the AspectJ project.
I'm not sure at all if it is even possible to change the source or byte code via annotations. From what your describing it looks as if aspect oriented programming could provide a solution to your problem.
Your annotations are pretty similiar to the pointcut concept (they mark a location where code needs to be inserted) and the inserted code is close the advice concept.
Another approach would be parsing the java source file into an abstract syntax tree, modify this AST and serialize to a java compiler input.
If your class extends a suitable interface, you could wrap it in a DynamicProxy, which delegates all calls to the original methods, except the call to test.
GWT 2.1.1 has very good framework - RequestFactory with all the EntityProxy and stuff.
I am looking for a way to serialize runtime instances that implement EntityProxy for debugging and logging etc. I do not care for format as long as it human readable.
To be more specific I would like to have something like the provided by Apache Commons Lang
ReflectionToStringBuilder
May be there is some way to use the JSON serialization mechanics that GWT has inside? if yes how to make it a bit more readable?
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
String stringRep = ReflectionToStringBuilder.toString(this);
There are at least 2 solutions:
First: Based on the idea by Thomas Broyer
public static String toString(EntityProxy entityProxy)
{
DefaultProxyStore store = new DefaultProxyStore();
Swap.requestFactory.getSerializer(store).serialize(entityProxy);
return store.encode();
}
Which produce something like this:
{"V":"211","P":{"1#2#biz.daich.swap.shared.dto.UserAccountProxy":{"O":"PERSIST","R":"2","Y":1,"T":"biz.daich.swap.shared.dto.UserAccountProxy","P":{"id":null,"items":null,"channelId":null,"lastActive":1296194777916,"name":null,"emailAddress":"test#example.com","lastReported":1296194777916,"lastLoginOn":1296194777916}}}}
Second: Based on the AutoBean framework
public static String toJson(EntityProxy entityProxy)
{
return AutoBeanCodex.encode(AutoBeanUtils.getAutoBean(entityProxy)).getPayload();
}
Which produce string like
{"emailAddress":"test#example.com","lastActive":1296194777916,"lastLoginOn":1296194777916,"lastReported":1296194777916}
The second is just what I need - it more readable in log.
I haven't tried it but have a look at RequestFactory#getSerializer, there's some sample code in the javadoc for the ProxySerializer.
If using the method
toJson(EntityProxy entityProxy)
change this to
toJson(BaseProxy proxy)
and then you can log Value and Entity Proxy objects.