Java-Design: Enum state? - java

I realize (having read other posts on SO as well) that it's bad design (or better said in my case it would also not make sense) to add state to enum constants.
Nevertheless i am finding myself right now in a situation where i need something similar to this.
An application i am writing uses error-constants (enum), which i am using to indicate errors by adding them to a Map<Error, ErrorInfo> (note that these are not application-errors, but "Errors" that are part of the application).
Well - i now realize that i actually also need to indicate an ErrorLevel of INFO, WARN, FATAL for these.
Since the ErrorLevel of an Error depends on the context it occurred in, i cannot statically assign ErrorLevel's to the Error-enums, in other words, an Error.E1 can be of ErrorLevel.WARN one time, but might be ErrorLevel.FATAL another time.
I am thinking about how i could best incorporate this ErrorLevel in my design, but all i have come up with up to now is, to introduce a new class which simply wraps an Error and an ErrorLevel and use it within the Map instead of Error.
Since Errors and their severity seem to me something that must be quite common, i am sure that there are smarter way to do this, so i would greatly appreciate your ideas on how to design this better.
--qu

If I understood your problem correctly, putting a transient state to the enum won't do the trick. As there is only one instance per enum-type by changing the error-level you would not only change it for the current error you are assessing but for all errors of the same type in the application.
You wrote, the errorlevel is depending on the context and at the same time that ErrorInfo describes the context of the occurance of the error. If you can calculate the errorlevel based on the errortype and the context, I would suggest some static method
public static ErrorLevel getLevel(Error, ErrorInfo) {
//..
}

I do not agree in total that it is always bad design adding mutable state to enums. Enums are like Singletons and whenever it makes sense to use a stateful singleton in your application, you can do the same with enum. Like with singletons we just have to keep in mind, that a state change has a pretty global effect.
For sure, stateful enums won't help in your case, because you want context specific error levels.
As an alternative, consider using a simple multimap:
Map<Context, Map<Error, ErrorLevel>> errors;
The idea is to store multiple maps for different contexts. So for a known context (I quickly invented a type...) you get the context specific parameter map.

Related

Zuul filter return value

What is the possible usage of ZuulFilter.run() return value?
All the examples (for instance Spring example) return null.
The official documentation says:
Some arbitrary artifact may be returned. Current implementation ignores it.
So why to have it at all?
I've used this lib in multiple projects and I never thought to look into and stumbled upon this question so I had to look. Just tracing the code in IntelliJ, it does look like the results are pointless.
I'm on zuul-core:1.3.1:
Looking at FilterProcessor, when the routing methods are called to route based on the type, they all call runFilters(sType) which ultimately get the the return Object in question of the implementing IZuulFilter classes. The trail seems to stop here.
I then stopped to looked at their test classes and nothing seems to do anything with the return Object either nor the ZuulFilterResult that wraps it.
I then thought, ok, well maybe there is a way to pass data from one IZuulFilter to another (e.g. from pre to route) but that doesn't seem possible either since FilterProcessor.processZuulFilter(ZuulFilter) doesn't do anything with the results and just passes it back to runFilters(sType) which we know ignores it.
My next line of questioning was, "well, perhaps you can provide your own FilterProcessor implementation and swap it out and actually use the Object somewhere". But alas, it looks like that isn't the case either unless you want/need to implement a lot more even into the ZuulServlet?
Lastly, I thought, "well, maybe it's just a convention thing". But java.lang.Runnable.run() is void and javax.servlet.Filter.doFilter is also void.
So for now, my best guess is that like all of us at some point in our careers, we sometimes fall into a YAGNI situation; perhaps this is just one example.

java - how to persist variable in JVM

I have an odd situation where i want to be able to be able to persist a variable in memory.. like a global variable I can pin in the JVM.
Is this possible? I remember doing something similar in college, but can't find it by googling. I have a logic problem that has some artificial constraints that make this the best possible solution.
EDIT 1:
I will need to update the value of the variable.
EDIT 2 :
I appreciate the responses guys. I'm a .net programmer and hadn't used java since college. Thanks again.
Yes, using a static field:
public class GlobalVariableHolder {
public static int globalVariable;
}
Note, however, that this is considered a bad practice and can lead to unexpected results that are hard to debug. The way to not use a global variable is to pass it around as an argument or methods where you need it.
If you are still sure you need this, in order to guard yourself as much as possible, use synchronization. Even better, if the variable is going to be primitive (int, long, etc), you can use AtomicInteger's getAndAdd() or addAndGet() method.
Usually you will end up storing these things in some kind of a global class--a class that is accessible from anywhere and has a controlled number of instances.
Singletons are commonly used for this. If you look up the pattern for a singleton and store your variable in that singleton (add a setter and a getter) you are on your way.
Doing this (as opposed to a public static variable) will give you some level of access control and traceability--for instance you can put debug statements in the getter if you find you are getting unpredictable results.
In the long run setters and getters and singletons are all bad code smells but no where near as bad as a settable public variable.
Later you may want to move the code that manipulates that variable into the singleton object and possibly convert the singleton to something you can fetch via IOC, but having a singleton is a much better place to start than with a public static.
Do you mean something that will exist across multiple invocations of java.exe, or do you mean a single variable that will be the same location in memory regardless of which thread within java.exe access it? Or do you mean a variable that can only be accessed if you're using JRockit? Or maybe just the JVM on your dev machine, but not on another system?
In the first case, you'd need another way to store it, like a config file.
In the second case, like Bozho says, use the static keyword.
In the third case, you'd probably need to use the System class and determine the JVM manufacturer (Assuming that's available from System - I'm not sure off the top of my head, and you'll learn more by looking up the API yourself).
In the fourth case, you're pretty much back to a config file.
Its not going to win any awards but this should work:
package mypackage;
public class MyGlobal {
public static String MY_GLOBAL_VAR = "my variable";
}
Any class within that JVM instance would be able to access MyGlobal.MY_GLOBAL_VAR.
Updated to allow update.

Possible to specify access to isAttribute vs getAttribute in JSP EL?

Our Topic object has BOTH isChannel and getChannel public methods. The object graph is too complex to change this. Channel has an Integer type.
We are migrating from one application server to Tomcat. When using this expression ${topic.channel.type}, in JSPs our current app server finds the getChannel method. However, Tomcat finds the isChannel method and we get errors since the return type is a Boolean, not a Channel. Is there a way to tell Tomcat to prefer getters over boolean public methods?
For now I'm just going to write a helper function or expose a new method, but I have a feeling I'm going to come across this quite a bit during the migration.
Unfortunately, you can't force a method call like that.
I have checked the Javabeans and EL specifications, but nowhere is specified what the preferred method is when both isXXX() and getXXX() methods are present. However, I do agree that it makes more sense to prefer the getXXX() one in this particular case. This should also be programmatically possible. I think it's worth the effort to report this as an issue against the Tomcat EL implementation.
In theory, this should be more of a JavaBeans issue than an EL implementation issue. One thing you might try is to find out how the java.beans.Introspector views your Topic class. One way to do that would be to run this code I wrote a while back for the Struts wiki. Depending on the complexity of your class, it might make sense to create an explicit java.beans.BeanInfo class to force the channel property to always be exposed as an Integer.

Customising log4j logging for sensitive data

I have a class which contains sensitive information (Credit card info, phone numbers etc).
I want to be able to pass this class to log4j, but have it obscure certain information.
If I have a class UserInformation which has getPhoneNumber, getCreditCardNumber methods, how would I customise log4j or this class so that it will obscure the numbers correctly.
I want the credit card number to be output as xxxx-xxxx-xxxx-1234 and the phone number to be output as xxxx-xxx-xxx given that these would be 1234-1234-1234-1234 and 1234-567-890
Thanks
You could try to implement this by writing a custom log record formatter that obscures those patterns. But I think that is a bit dodgy ... because someone could accidentally or deliberately circumvent this by tweaking the logger configuration files, etc.
I think it would be better idea to do one of the following, depending on how you are assembling the log messages:
Change the logger calls in your code to assemble the log messages using alternative getter methods on UserInformation that obscure the sensitive fields.
Change the toString method on UserInformation to obscure the details.
I'd write an obfuscating formatter for those fields and use that to write to the log file.
I'd also ask why you would continue to use String primitives instead of objects that could encapsulate the appropriate behavior.
Update: The best option is probably to wrap your real objects in an Obfuscated-ClassName wrapper that implements the same interface but returns obfuscated versions (by delegating to the real object and obfuscating the result) and hand those to the logging system. This only works if you are actually passing in these objects yourself, and not if they are part of an object tree - that might make the whole situation a bit more complex.
old:
Maybe you should just add getPhoneNumberForLogging()/getObfuscatedPhoneNumber() type functions? (Of course you have to take into account that if you hand an object containing this data to another object/process you cannot control access to the 'normal' functions so technically you don't shield the data at all - although it might be possible to make the methods that show sensitive data package local accessible only?)
You could also investigate the call stack on every call and try to figure out if you want to return the full data or the obfuscated version - this will add quite a bit of overhead and might be very tricky to debug.

In Java, how can I construct a "proxy wrapper" around an object which invokes a method upon changing a property?

I'm looking for something similar to the Proxy pattern or the Dynamic Proxy Classes, only that I don't want to intercept method calls before they are invoked on the real object, but rather I'd like to intercept properties that are being changed. I'd like the proxy to be able to represent multiple objects with different sets of properties. Something like the Proxy class in Action Script 3 would be fine.
Here's what I want to achieve in general:
I have a thread running with an object that manages a list of values (numbers, strings, objects) which were handed over by other threads in the program, so the class can take care of creating regular persistent snapshots on disk for the purpose of checkpointing the application. This persistor object manages a "dirty" flag that signifies whether the list of values has changed since the last checkpoint and needs to lock the list while it's busy writing it to disk.
The persistor and the other components identify a particular item via a common name, so that when recovering from a crash, the other components can first check if the persistor has their latest copy saved and continue working where they left off.
During normal operation, in order to work with the objects they handed over to the persistor, I want them to receive a reference to a proxy object that looks as if it were the original one, but whenever they change some value on it, the persistor notices and acts accordingly, for example by marking the item or the list as dirty before actually setting the real value.
Edit: Alternatively, are there generic setters (like in PHP 5) in Java, that is, a method that gets called if a property doesn't exist? Or is there a type of object that I can add properties to at runtime?
If with "properties" you mean JavaBean properties, i.e. represented bay a getter and/or a setter method, then you can use a dynamic proxy to intercept the set method.
If you mean instance variables, then no can do - not on the Java level. Perhaps something could be done by manipulations on the byte code level though.
Actually, the easiest way to do it is probably by using AspectJ and defining a set() pointcut (which will intercept the field access on the byte code level).
The design pattern you are looking for is: Differential Execution. I do believe.
How does differential execution work?
Is a question I answered that deals with this.
However, may I suggest that you use a callback instead? You will have to read about this, but the general idea is that you can implement interfaces (often called listeners) that active upon "something interesting" happening. Such as having a data structure be changed.
Obligitory links:
Wiki Differential execution
Wiki Callback
Alright, here is the answer as I see it. Differential Execution is O(N) time. This is really reasonable, but if that doesn't work for ya Callbacks will. Callbacks basically work by passing a method by parameter to your class that is changing the array. This method will take the value changed and the location of the item, pass it back by parameter to the "storage class" and change the value approipriately. So, yes, you have to back each change with a method call.
I realize now this is not what you want. What it appears that you want is a way that you can supply some kind of listener on each variable in an array that would be called when that item is changed. The listener would then change the corresponding array in your "backup" to refect this change.
Natively I can't think of a way to do this. You can, of course, create your own listeners and events, using an interface. This is basically the same idea as the callbacks, though nicer to look at.
Then there is reflection... Java has reflection, and I am positive you can write something using it to do this. However, reflection is notoriously slow. Not to mention a pain to code (in my opinion).
Hope that helps...
I don't want to intercept method calls before they are invoked on the real object, but
rather I'd like to intercept properties that are being changed
So in fact, the objects you want to monitor are no convenient beans but a resurgence of C structs. The only way that comes to my mind to do that is with the Field Access call in JVMTI.
I wanted to do the same thing myself. My solution was to use dynamic proxy wrappers using Javassist. I would generate a class that implements the same interface as the class of my target object, wrap my proxy class around original class, and delegate all method calls on proxy to the original, except setters which would also fire the PropertyChangeEvent.
Anyway I posted the full explanation and the code on my blog here:
http://clockwork-fig.blogspot.com/2010/11/javabean-property-change-listener-with.html

Categories

Resources