Suppose I have a class with an annotation, e.g.:
#MyConfig
class MyConfiguration {
#MyParameter
String parameter;
}
If I know an instance of this class exists (for instance, one was constructed in another thread) how can I get a reference to the instance elsewhere. I'm trying to find the instance by its #Annotation.
You cannot simply conjure up a reference to an object based on its type or annotations, nor should you really want to. The primary reason for this is garbage collection - the JVM cleans up memory for you as objects fall out of scope; if you could create new references dynamically, the garbage collector would not be able to safely clean anything up, and you'd rapidly run out of memory.
That said there's many ways you can build up functionality like you're describing pretty simply, so that you can look up an object by its type.
The easiest (and arguably best) way to do this is to simply register the instance you want, using a Map (consider Guava's ClassToInstanceMap). While you have to explicitly add to the map, that is actually going to be a lot cleaner for you in terms of code-compartmentalization. Even if you make the caching behavior a static method on the annotation, or something like that, separating construction from caching is a good practice to get into.
// somewhere accessible to both the constructing and accessing code, such as a
// public static field on the Annotation
Map<Class<? extends Annotation>,Object> annotationMap = new HashMap();
// wherever the instance is constructed
annotationMap.put(MyConfig.class, new MyConfiguration());
// wherever the instance is needed
MyConfiguration myConf = (MyConfiguration)annotationMap.get(MyConfig.class);
You've likely noticed that this holds Object values, because any class can theoretically be annotated, so we have to explicitly cast. This will work, assuming you enforce what types are inserted into the map, but it is fragile. Truth be told, the idea of associating annotations with instances is fragile in itself, so this is likely the least of your worries.
If you want to ensure that the most recently constructed MyConfiguration is accessible like this, you could put the above in it's constructor, like so:
#MyConfig
class MyConfiguration {
public MyConfiguration() {
// note this is potentially dangerous, as this isn't finished constructing
// yet so be very cautious of this pattern, even though it might seem cleaner
annotationMap.put(MyConfig.class, this);
}
}
Now you can be confident that, if a MyConfiguration instance exists, it is accessible from annotationMap by its annotated type.
As I hinted above however, I suspect neither of these are good solutions for you. And really the reason why is because annotations are not designed at all to let you refer to instances; they are instead meant to let you know things about an instance once you already have one. So let me ask you, why do you think you need to lookup an object by its annotation? Is there another pattern you can use instead?
I suspect what you're really trying to build is a Singleton - you expect your runtime to have exactly one instance of MyConfiguration, and you want all your code to easily access it. A standard pattern for this is:
#MyConfig
class MyConfiguration {
private static MyConfiguration INSTANCE = null;
public static MyConfiguration getInstance() {
// note this is not thread-safe
// see the above link for several thread-safe modifications
if(INSTANCE == null) {
INSTANCE = new MyConfiguration();
}
return INSTANCE;
}
This lets any code call MyConfiguration.getInstance() and be able to access the instance. That said, Singletons are generally considered bad practice (though less so than what you're describing). Ideally, you should be passing your configuration instance around to whatever classes or threads need it. Passing your references explicitly, rather than relying on a semi-magical cache or global state like a singleton, is far and away the "right" way to deal with the problem you're facing.
Related
I marked an immutable data model class as final to make sure the only way to change its values is to create a new instance. (Unfortunately, the fields cannot be final because they needs to be populated by Hibernate.)
This worked well until I wanted to check another class throws the correct exception when called with an invalid instance of the model. The constructor of the model validates the arguments so reflection must be used to set the fields. This is extremely clumsy since the model have quite a few fields and the field names have to be hard-coded.
I can't mock the model either due to it being final. (Is it also debatable whether an interface should be used to enable mocking while keeping the class immutable. By having an interface, there's no way to programmatically mandate the methods must return the same value throughout the life of the instance.)
What do people usually do in this case? Is there any standard approach to this?
Generally speaking, you shouldn't want to mock data objects. Data objects should have no logic and no external dependencies, so there's not really much use to mocking the objects. Instead make it very easy to create fake instances that you can populate in methods as you'd like.
Furthermore, there are a few other reasons you might want to avoid treating a Hibernate-persisted object as immutable:
Hibernate-provided objects are inherently not thread-safe and therefore lose the thread-safety advantages that immutable value objects typically provide.
You may find your objects are actually proxies, possibly undercutting the final semantics.
Hibernate-controlled objects operate completely differently whether their session is still open (attached vs detached) making them a very poor choice for an immutable object. If your immutable object depends on session lifetime, it's not really immutable.
It sounds like some objects may be valid or invalid at the application layer, beyond database-layer validation. That makes it a little harder to encapsulate your validation concerns.
You are required to have a public no-arg constructor, which is antithetical to the kind of instance control typical of immutable value objects.
Because the objects are inherently mutable, it is more complicated to override equals and hashCode.
My advice? If you need more immutability and data validation guarantees than a Hibernate DAO can grant you, then create a real final immutable class with final fields (or a private constructor and static factory method), and then make a constructor (or static factory method) that copies in values from your Hibernate DAO.
If you decide this option, you are stuck with the overhead of having two data objects that change roughly in parallel, but you also get the benefit of separating concerns (in case the Hibernate object should diverge) and the ease of a truly-immutable, equals-and-hashcode-overriding, session-agnostic, guaranteed-valid object that you can easily create for tests.
For clarity, making a class final prevents it from being sub-classed. This is good in cases where the class doesn't need to be further refined.
Marking a class level variable as final means that it will only get assigned once. For primitives and immutable objects like String, this has the side effect of making the variable immutable (by default).
However, for mutable objects like Date, your variable will always reference the same instance, but others with access to that instance would still be able to change it's state. For example if you had a method
public Date getCreatedDate(){
return this.created; // class variable declared as private final Date created...;
}
Then any caller could access the created instance and change it's state. You would be better to only return truly immutable values, or return a clone.
public Date getCreatedDate(){
return this.created.clone();
}
EDIT
"I marked an immutable data model class as final to make sure the only way to change its values is to create a new instance"
Your issue as I understand it is that Class A has a dependency on Class B. You wish to test class A and you are unable to mock class B, as you have marked it as final. You marked Class B as final to make it immutable (preventing it's internal state being changed). This is incorrect, as marking a class final prevents it from being sub-classed. It has nothing to do with the ability to change the internal state of an instance.
Your use of final does not have the desired effect. Marking the fields as final is not an option, and would not make the class immutable for the reasons stated above. The only way to protect your data is to prevent clients of your data from having access to the objects that make up it's internal state.
Assuming, that you won't be the only developer, you need to protect the users of your data from unintentional updates. Ensuring that you return clones from getters is one approach. Having team members sub-class and change data is just bad programming, not unintentional, and could be managed through policy and code review.
If you wish to protect your code from external interference by unknown developers (for example writing code that utilises the same namespace to inject their code), then other approaches are available such as package sealing.
I need to be able to mark methods so that they throw a RuntimeException if they are called more than once.
I am trying to enforce some single assignment semantics and the number of parameters to my class is too large to put in a single constructor and I need to be able to make these classes JAXB aware as well, so the objects need to be mutable but I want to enforce single assignment semantics.
I am pretty sure I can do this with Aspects, but I would really like to be able to use my own Annotations processor instead.
I know how to do this with Decorators in Python.
How do I write an Annotation processor that can intercept calls to the annotated method at runtime and not just at compile time?
I think I am on to something with with Dynamic Proxies intercepting the method calls, I just need to figure out how to integrate them with my Annotation processor.
Dynamic Proxies require you to use an Interface, that is way to cumbersome, I have a CGLib MethodInterceptor working now, much less requirements on what gets intercepted and decorated, at the expense of adding a dependency.
Nope, there's nothing ready-to-use. And AspectJ seems the only way to make it work in a more general manner. As JB Nizet noted - the annotation should have a parser to parse it.
However, I would advise for a better and simpler solution - the Builder pattern. What does it look like:
you have a FooBuilder (it may also be a static inner class) which is mutable and has a setter and getter for each of the fields
FooBuilder has a build() method that returns an instance of Foo
Foo has a constructor that takes only FooBuilder, and you assign each field there.
That way:
Foo is immutable, which is your end goal
It is easy to use. You only set the fields that you need. Something like:
Foo foo = new Foo.FooBuilder().setBar(..).setBaz(..).build();
That way the builder can be JAXB-aware. For example:
FooBuilder builder = (FooBuilder) unmarshaller.unmarshal(stream);
Foo foo = builder.build();
JAXB objects need to be mutable, and your requirement is an immutable object. Hence the builder comes handy to bridge that.
This question shows some resemblance with question Applying CGLib Proxy from a Annotation Processor.
If you want to be able to change the behavior of the original source code in an annotation processor have a look at how http://projectlombok.org/ achieves this. The only downside IMO is that lombok relies on com.sun.* classes.
Since I need this kind of stuff myself I wonder if someone knows of a better way to achieve this, still using annotation processors.
You can configure JAXB to use field (instance variable) access using #XmlAccessorType(XmlAccessType.FIELD). This will allow you to do what you need to with the set method:
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
You can also use JAXB's XmlAdapter mechanism to support immutable objects:
http://blog.bdoughan.com/2010/12/jaxb-and-immutable-objects.html
Instead of using an annotation you can use.
assert count++ != 0;
You would need one counter per method.
I had a similar requirement. Long story short when you inject components in Spring the cyclic dependency situation like A depends on B and B depends on A is perfectly fine, but you need to inject these components as fields or setters. Constructor injection causes a stack overflow. Therefore I had to introduce a method init() for these components, which unlike constructors might be erroneously called more than once. Needless to say boilerplate code like:
private volatile boolean wasInit = false;
public void init() {
if (wasInit) {
throw new IllegalStateException("Method has already been called");
}
wasInit = true;
logger.fine("ENTRY");
...
}
started to emerge everywhere. Since this is nowhere close to being a critical spot of the application, I made a decision to introduce an elegant thread-safe one-liner solution favoring conciseness over speed:
public class Guard {
private static final Map<String, Object> callersByMethods = new ConcurrentHashMap<String, Object>();
public static void requireCalledOnce(Object source) {
StackTraceElement[] stackTrace = new Throwable().getStackTrace();
String fullClassName = stackTrace[1].getClassName();
String methodName = stackTrace[1].getMethodName();
int lineNumber = stackTrace[1].getLineNumber();
int hashCode = source.hashCode();
// Builds a key using full class name, method name and line number
String key = new StringBuilder().append(fullClassName).append(' ').append(methodName).append(' ').append(lineNumber).toString();
System.out.println(key);
if (callersByMethods.put(key, source) != null) {
throw new IllegalStateException(String.format("%s#%d.%s() was called the second time.", fullClassName, hashCode, methodName));
}
}
}
Now, since I prefer building applications within DI frameworks it might sound natural to declare Guard as a component, then inject it, and call an instance method requireCalledOnce instead. But due to its universal flavor, static reference yields more sense. Now my code looks like this:
private void init() {
Guard.requireCalledOnce(this);
...
}
and here is an exception upon the second invocation of init of the same object:
Exception in thread "main" java.lang.IllegalStateException: my.package.MyComponent#4121506.init() was called the second time.
at my.package.Guard.requireCalledOnce(Guard.java:20)
at my.package.MyComponent.init(MyComponent.java:232)
at my.package.MyComponent.launch(MyComponent.java:238)
at my.package.MyComponent.main(MyComponent.java:48)
I have Guice-injected objects which have two lifecycle methods bind() and unbind(). The method bind() is called automatically after the object is instantiated by Guice using following annotated method:
#Inject
final void autoBind() {
bind();
}
What I want to do is to call the method unbind() on the old (current) object before a new instance of the object is created by Guice. How do I do that?
Thanks in advance!
First of all, I would not advise that you just annotate arbitrary methods with #Inject. Keep it to constructors, and occasionally for optional injection and/or field injection.
What you are trying to do does sound a bit weird, and I'm not sure it's exactly what you want. Can you please provide more background on what you're trying to do because maybe a different approach is better. There are definitely some concerns here with thread safety and how you manage references.
Based on what you described, an approach like what #meverett mentioned would probably work. If the objects you have are Foos, it would look something like this.
// Later on be sure to bind(Foo.class).toProvider(FooProvider.class);
final class FooProvider implements Provider<Foo> {
private final Provider<Foo> unboundFooProvider;
private Foo currentInstance;
#Inject FooProvider(#Unbound Provider<Foo> unboundFooProvider) {
this.unboundFooProvider = unboundFooProvider;
}
#Override public Foo get() {
if (currentInstance != null) {
currentInstance.unbind();
}
currentInstance = unboundFooProvider.get();
currentInstance.bind();
return currentInstance;
}
}
NOTE that your #Unbound Foo provider would generate Foos without invoking any special methods. The regular FooProvider keeps track of state and deciding when to bind() and unbind() the instances. Please be careful with how you manage multiple instances and use them with multiple threads.
Also, just to be clear: I'm using #Unbound since the methods you want to invoke are called bind() and unbind(). I'm not using "bound" in the Guice sense.
Also note... off the top of my head I'm pretty sure Providers are treated as singletons, so maintaining state like this will work. If it didn't, you could obviously just create a level of indirection with some kind of singleton factory (but that shouldn't be necessary).
Previous responses address other concerns nicely, so to just answer the question:
Netflix introduced governator in github in 2012 to "enhance Google Guice to provide ... lifecycle management". It provides annotations (#PreConfiguration, #PostConstruct, #PreDestroy, and others), classpath scanning & auto binding, and other features. Bootstrapping is straight forward.
I suppose you could have a provider that keeps a reference to the current object. When you call get on the provider it would unbind the last object, construct the new one and save the reference to it.
though I'm not really sure why you would want to do something like this since other objects can in theory still be referencing it
I am a little confused here with this findbugs warning in eclipse.
public class MyClass {
public static String myString;
}
public class AnotherClass {
public void doSomething() {
MyClass.myString = "something";
}
}
This gives me a findbugs warning "write to static field from instance method", however this does not give me a warning:
public class MyClass {
public static String myString;
}
public class AnotherClass {
public void doSomething() {
doAnotherThing();
}
public static doAnotherThing() {
MyClass.myString = "something";
}
}
How is this any different?, and why is writing to a static variable from an instance method a bad practice?, I assume it has to do with synchronization, but it is still not clear to me.
I know this looks like the variable should be final, but I am loading the value from a properties file.
Its a form of aliasing, which may be counter-intuitive. Counter-intuitive code hampers ease of maintenance.
Logically, we expect instance methods to affect that instance's data. We expect static methods to affect static data.
Let's rename doSomething to initialize:
...
a.initialize();
...
b.initialize();
...
The reader of this code may not immediately realize that the instances of a and b are actually affecting the same data. This may be a bug since we're initializing the same memory twice, but its non-obvious since it seems reasonable that we may need to call initialize on each instance.
However, the the code were:
...
MyClass.initialize();
...
MyClass.initialize();
...
In this case, its more intuitive that we're likely affecting the same static data and this is likely a bug.
This is similar to the common version of aliasing where two variables in the same scope point to the same instance.
For your last example,
an instance calls a static method
The fact that an instance method is calling a static method isn't expected to raise flags. The examples were this is useful far outweigh where its likely a problem.
a static method of one class affects another class' static data
In one sense, it should generate a different, but similar warning: that one class is messing with the data of another class. However, by making the static variable public is a way of tacitly approving of this, so such a warning isn't necessary.
Keep in mind that FindBugs is simply trying to flag potential likely problems, not every possible problem, in your code. Your first example is likely a potential maintenance issue that you need to examine whether its a real problem. Your second example is likely not a problem or it is a real problem that is too similar to use cases where it is not a problem.
There aren't many use cases for why you would want to change a static field.
Remember that if you set this field to a new value that this value has changed for all instances of this class.
This might get you into trouble in a multi-threaded environment, where more than one thread is calling doSomething(). Proper synchronisation is required.
In 99% of all cases, you want your instance methods to change the non-static fields only, which is why findbugs warns you.
And findbugs isn't clever enough to find out about your instance method indirectly changing the field in your second example :)
This is what FindBugs has to say about this: http://findbugs.sourceforge.net/bugDescriptions.html#ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD
This is my take, so take it with a grain of salt. You mentioned synchronization issues, which are a major reason for this warning, but more importantly, the two cases are fundamentally operating on different conceptual "levels" of data. Instance methods are "owned" by objects and modify data that describes individual instances. Class methods are generic operations and state that, while related to the class, are not related to individual objects. Thus, modifying that state from within each instance would probably (but not necessarily) be a poor design decision.
Because changing a static field changes it for all instances, causing untold problems if not properly synchronised.
If you're reading in a properties file to set shared fields, then do it in a static method. Alternatively, refactor the fields into a separate singleton instance that the other class can only read from. If you're only going to have one instance, then use a singleton pattern and make the fields non-static.
Static methods should only affect static data, and instance methods should only affect instance data.
I don't think synchronization (mentioned in several answers) has any bearing on this. After all, static methods can be called from multiple threads just as easily as can instance methods.
The reason for the warning (not very well explained by the FindBugs documentation) is, I think, hinted at by a couple of answers: it's suspicious and possibly a mistake. Like Jochen Bedersdorfer said, there aren't all that many use cases where you want to assign to a static variable in one class from an instance method in another. Just like
while (x = y) {
// ...
}
isn't technically an error (and actually legal Java if x and y are boolean), it's almost always a mistake. Similarly, the authors of FindBug felt the same about the subject case.
I'd like to be able to specify that an object's member variables are immutable once the object has been "initialized", which to me means after it has been injected with any dependencies, and has performed any other initialization operations that it can only perform after DI.
Are there languages that satisfy my interest - that formalize DI, initialization, and support immutability in this fashion? Maybe it's dumb to make them a part of a language; maybe not. I'm not sure.
Today I program in Java, but I can't use "final" nearly as much as I'd like, because those phases happen after the constructor has finished execution. Any advice on how to get what I want with Java? I guess I could have my objects implement a base class so that those phases happen before the constructor finishes, or use aspects to do the same.
Thoughts?
There are two main ways of producing immutable objects:
use the builder/factory pattern - the builder may be mutable, but the objects it creates are immutable, usually implemented with final fields. You can also combine the two, so the object itself is used to build new instances, usually via "mutator" methods that change state on a separate, new instance. Spring's FactoryBean is an example of this.
create a MutableObject subclass, which maintains a flag for mutable state. All your mutators check the mutable state before making any changes - if the object has been set to immutable, then the check throws an exception, otherwise the change goes ahead.
The first approach is quite Spring-centric, since it requires implmentation of a spring-specific interface. You can create factory beans that are regular beans, via factory-method/factory-bean attributes on a bean, which removes the spring dependency from your code.
Using the second approach is particularly useful with spring. You can instruct spring to call a method after bean initialization, e.g. seal() which seals the object - makes it immutable. Alternatively, you can implement a small BeanFactoryPostProcessor to do this automatically without having to remember to set the init-method="seal". on each immutable bean.
I guess it depends on what you want out of the immutability. If you want the guaranteed thread safety (where everything must be declared final, including the dependencies) then I think factory, builder or constructor injection are your only options.
If however you just want immutability of state, then declaring the state variables final should be enough. Even the immutable String class has a mutable field in its implementation (a cache of the hashcode value). As long as your code otherwise ensures that an instance is not available without injection, all should be well.
In Java, you can use a builder to initialize an immutable object in its constructor, so you'd shy away from setters.
If you use Scala, though, immutability is the default.
In Java, if you're using mutator methods to do your setting anyhow, it's pretty cheap (though also pretty ugly in my eyes) to add logic to prevent alterations once the object is initialized.
public void setMyProperty(String newValue) {
checkInitialized();
myProperty = newValue;
}
public void checkInitialized() {
if ( initialized ) {
throw new IllegalStateException("Setter called after initialization");
}
}
At best though this is giving a dynamic check. It doesn't give you any static feedback over what you would have already had.
To specify that a class is immutable, you can use the #Immutable annotation.
You can see the Javadoc here.
This works well with the Findbugs plugin in Eclipse.
#Alexander:
As I understand him, he asked how to specify that a class is immutable. Not how to write an immutable class. This annotation can give you tool support to verify that you don't have a bug in your class that you claims are immutable.
A snippet from the Javadoc:
Of necessity this means that all
public fields are final, and that all
public final reference fields refer to
other immutable objects