JUnit: initialization of static final attributes - java

Oftentimes in my unit tests I have fixtures that are read from resource files and stored into a static attribute on the test class:
public class TestFoo {
private static String fileContents;
#BeforeClass
public static void setup() throws IOException {
fileContents = ... read TestFoo.class.getResourceAsStream("filename") ...
}
}
Which works, but the problem I have is that I generally don't like non-final static data in my tests as it allows for the possibility of one test case to affect the output of another (in the above example if one test reassigned fileContents to something else, then there would be side-effects in other tests that make use of the fixture data).
If I add the final modifier though, then the assignment has to happen at declaration, which is a problem when the initialization is non-trivial (such as in the above example where a checked exception could be triggered by the initialization code). An alternative is to use a static initializer block:
public class TestFoo {
private final static String fileContents;
static {
try {
fileContents = ... read TestFoo.class.getResourceAsStream("filename") ...
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
But I don't particularly like this approach due to the verbosity of having to write a try/catch.
Which approach is more common/idiomatic Java, or is there a better/more typical way to have a static final resource initialized?

I'd use #BeforeClass because it's less verbose. If you fear that someone might accidentally overwrite the value, you could also use #Before. Unless the file is very large, the runtime overhead is probably negligible.

Related

is FindBugs 'JLM_JSR166_UTILCONCURRENT_MONITORENTER' safe to ignore in this case

I have a library that I am required to use that has a dangerous initialization of a static value (the classes have been stripped down to the minimum for the example):
public TheirBaseClass {
public static String PathToUse = null;
public BaseClass(){
PathToUse = "Configured";
// ...
// do some other stuff with other side effects
// ...
}
}
I have a case where I attempt to read from the value ConfigValue without instantiating the class (to avoid some of the sideeffects).
Paths.get(TheirBaseClass.PathToUse).toFile()....
This causes a NullPointerException
Because I am required to use this class, I am looking to inherit from it, and attempt to take action to ensure that initialization has taken place when accessing the static.
public MyBaseClass extends TheirBaseClass{
private static final AtomicBoolean isInitialized = new AtomicBoolean(false);
static {
MyBaseClass.Initialize();
}
public static void Initialize(){
// FindBugs does not like me synchronizing on a concurrent object
synchronized(isInitialized){
if( isInitialized.get() ){
return;
}
new TheirBaseClass();
isInitialized.set(true);
}
}
public MyBaseClass(){
super();
}
}
Which allows me to
MyBaseClass.Initialize();
Paths.get(MyBaseClass.PathToUse).toFile()....
This seems to be working reasonably well (and resolves some other phantom defects we've been having). It allows TheirBaseClass to function naturally, while allowing me to safely force initialization in the couple of cases I may need to.
However when I run FindBugs against this code, I get JLM_JSR166_UTILCONCURRENT_MONITORENTER. After reading the description, I agree that the use of AtomicBoolean could be dangerous because someone else could change the value, but...
I think its safe to ignore in this case (but have a doubt)
I generally prefer to rewrite code than put an ignore marker in place
Am I actually doing something dangerous (and just don't see it)? Is there a better way to do this?
Unfortunately, using a different TheirBaseClass is not an option.
Related
Are Java static initializers thread safe?
You might find it easier to adapt the lazy holder idiom:
public MyBaseClass {
private static class Initializer {
static {
new TheirBaseClass();
}
// Doesn't actually do anything; merely provides an expression
// to cause the Initializer class to be loaded.
private static void ensureInitialized() {}
}
{
Initializer.ensureInitialized();
}
// Rest of the class.
}
This uses the fact that class loading happens only once and is synchronized (within a single class loader). It happens only when you instantiate a MyBaseClass.

How to handle Exception from Singleton java?

I have a singleton class
public class SingletonText {
private static final CompositeText text = new CompositeText(new TextReader("text/text.txt").readFile());
public SingletonText() {}
public static CompositeText getInstance() {
return text;
}}
And TextReader constructor that could throw FileNameEception
public TextReader(String filename) throws FileNameException{
if(!filename.matches("[A-Za-z0-9]*\\.txt"))
throw new FileNameException("Wrong file name!");
file = new File(filename);
}
How can I rethrow it to main and catch it there?
Main class
public class TextRunner {
public static void main(String[] args) {
// write your code here
SingletonText.getInstance().parse();
System.out.println("Parsed text:\n");
SingletonText.getInstance().print();
System.out.println("\n\n(Var8)Task1:");
SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[AEIOUaeiou].*", new FirstLetterComparator());
System.out.println("\n\n(Var9)Task2:");
SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[A-Za-z].*", new LetterColComparator());
System.out.println("\n\n(Var16)Task3:");
String result = SubStringReplace.replace(SingletonText.getInstance()
.searchSentence(".*IfElseDemo.*"), 3, "EPAM");
System.out.println(result);
}}
Static block is executed only when class is loaded for the first time, so you can have something as below which will allow you to re-throw the exception. In you main method, you will surround getInstance() invocation in a try-catch block and then in catch you can do whatever you are looking for.
In case of exception, this exception will be thrown and re-thrown (from you static block) only once, at time of class loading. What #Alexander Pogrebnyak has said is also true.
Looking at the code you have provided, since you are always reading text/text.txt files so below approach will work. In case you are looking to read different files and then re-throwing exception then that becomes all together a different story, and you hadn't asked that part neither the code you have provided shows the same. In any case, if that's what you are looking for then:
you need to create a singleton object of your CompositeText class.
create a setter method will create an object TextReader class using the file name string passed.
that setter method will have the try-catch block, and in the catch block you will re-throw the exception so that you can catch again in main method.
P.S.: since static blocks are executed only once when class is loaded and class is loaded only once per JVM (until you have custom class loaders and overriding the behavior) so this ensures that this singleton is thread-safe.
Code:
public class SingletonText {
private static CompositeText text = null;
static{
try {
text = new CompositeText(new TextReader("text/text.txt").readFile());
} catch (FileNameException e) {
// TODO: re-throw whatever you want
}
}
public SingletonText() {}
public static CompositeText getInstance() {
return text;
}
}
try to lazy initialze the singleton.
something like this:
public class SingletonText {
private static CompositeText text;
public SingletonText() {
}
public static CompositeText getInstance() {
if (text ==null) {
text = new CompositeText(new TextReader("text/text.txt").readFile());
}
return text;
}
}
Also, you need to declare the constructor private, and if it multi-threaded application you need to synchronized the new statement with double check locking. see this in wiki:
https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
Enjoy..
You will get java.lang.ExceptionInInitializerError when your singleton static initializer will fail.
As a cause it will have your FileNameException.
If you don't do anything, default exception handler will print the whole stack trace to standard error.

Expression that behaves differently inside a static method

I'm trying to write an expression or series of statements of Java source code that when written inside a static method evaluates to null, but if the method is non-static evaluates to this.
My initial idea was to 'overload' on static vs non-static, as below:
public class test {
public void method1() {
System.out.println(getThisOrNull());
}
public static void method2() {
System.out.println(getThisOrNull());
}
private static Object getThisOrNull() {
return null;
}
private Object getThisOrNull() {
return this;
}
public static void main(String[] args) {
test t = new test();
System.out.println(t);
t.method1();
t.method2();
}
}
Unfortunately this isn't actually legal Java, you can't 'overload' like that and it just gives a compiler error:
test.java:14: error: method getThisOrNull() is already defined in class test
private Object getThisOrNull() {
^
1 error
Clearly in an ideal world I wouldn't write it like that to begin with, but the problem is this code will be generated automatically by a tool that is not really semantically or syntactically enough to distinguish between the static vs non-static case.
So, how can I write some source code that, although byte for byte identical compiles and behaves differently in depending on the presence of the static modifier for the method?
This can be achieved with a trick and a bit of help from Java's reflection facilities. It's ugly, but it works:
import java.lang.reflect.Field;
public class test {
public void method1() {
System.out.println(getThisOrNull(new Object(){}));
}
public static void method2() {
System.out.println(getThisOrNull(new Object(){}));
}
private static Object getThisOrNull(final Object o) {
for (Field f: o.getClass().getDeclaredFields()) {
if (f.getType().equals(test.class)) {
try {
return f.get(o);
}
catch (IllegalAccessException e) {
// Omm nom nom...
}
}
}
return null;
}
public static void main(String[] args) {
test t = new test();
System.out.println(t);
t.method1();
t.method2();
}
}
This compiles and runs as hoped for:
test#183f74d
test#183f74d
null
The trick that makes this possible is the use of new Object(){}, which creates a new, anonymous class within the existing method that we're trying to figure out if it's static or not. The behaviour of this is subtly different between the two cases.
If the goal were just to figure out if the method is static or not we could write:
java.lang.reflect.Modifiers.isStatic(new Object(){}.getClass().getEnclosingMethod().getModifiers())
Since we want to get this (when available) we need to do something slightly different. Fortunately for us classes defined within the context of an instance of an object in Java get an implicit reference to the class that contains them. (Normally you'd access it with test.this syntax). We needed a way to access test.this if it existed, except we can't actually write test.this anywhere because it too would be syntactically invalid in the static case. It does however exist within the object, as a private member variable. This means that we can find it with reflection, which is what the getThisOrNull static method does with the local anonymous type.
The downside is that we create an anonymous class in every method we use this trick and it probably adds overheads, but if you're backed into a corner and looking for a way of doing this it does at least work.

How to force the static block running in each test method?

I found static block is running only once when I execute multiple JUnit tests. How can I force it to run for each test method? I am using latest JUnit 4.8.2
Also, according to xUnit design principle, every method should be totally independent on others. Why static block only be executed once?
#Test TestMethod1 () {
Accounts ac = new Accounts();
ac.method1(); //kill the thread inside
}
#Test TestMethod2 () {
Accounts ac = new Accounts();
ac.method2(); // the thread is no longer available!!
}
class Accounts {
static {
// initalize one thread to monitor something
}
}
This even happens when TestMethod1 and TestMethod2 are in the different Test Classes.
static blocks are only executed on class loading because that is what they are: class initializers. To have a static block run multiple times would require you to unload the class (not an easy thing to do...).
If you need to use static blocks, you can come up with ways to test them. Why not unwrap the block into a public (static) method? All you have to do in that world is test the method:
static {
staticInitMethod();
}
public static void staticInitMethod(){
//insert initialization code here
}
you also might be able to get away with just an ordinary initializer
{//not static
//insert initialization code here
}
Although, the truth is most code doesn't need to use initializers like this at all.
Edit: Turns out Oracle likes the static method approach http://download.oracle.com/javase/tutorial/java/javaOO/initial.html
Why static block only be executed once?
Because that is the whole point of static initializer blocks!
Or to put it another way, if you want some initialization code to execute multiple times, put it in a regular constructor or method, or (in a tiny number of cases) a non-static initializer block.
In the context of JUnit, the normal way to implement test startup and shutdown code using setUp() and tearDown() methods.
If you are trying to unit test the execution of static initialization in your own code, you are in for a rough road I think. But then, unit testing of code with static state (e.g. singletons) is always difficult ... and that's one of the reasons that people think that static state is a bad idea.
Consider using a Dependency Injection (aka Inversion of Control) framework instead of singletons.
Alternatively, consider modifying your singletons / static initialization code to make it easier to test. For instance, add a static method that allows a test to re-execute the initialization. (And before you say that this breaks the singleton pattern: yes I know. You need to choose between design / implementation "purity" and ease of testing.)
Is the static code for the tests for the class being tested?
If the code is static so the tests can share, then you need to move the code into its own class. Then either have the test class constructor instantiate a static instance or create a test suite that does the same thing.
If you want each test to stand alone, then move what you are doing in your static block into the setup()/teardown() methods, it's what they are there for.
Static block is executed only once when first time class is loaded into JVM. Junit provide #Before annotation which is basically used for required initialization fro test case. This can be used for executing static blocks of class. for example I have following class Car
public class Car implements Vehicle{
private String type = "lmv";
static {
VehicleFactoryWithoutRefl.getInstance().registerVehicle("car", new Car());
}
#Override
public void moveForward() {
}
#Override
public String getType() {
return type;
}
#Override
public Vehicle createVehicle() {
return new Car();
}
}
and I want to execute static block of this class in Junit before creating the car instance. I have to load this class in setUp() using class.forName("package.ClassName") Junit code.
public class TestFactory {
#Before
public void setUp() {
try {
Class.forName("com.cg.dp.factory.Car");
} catch (ClassNotFoundException e) {
//e.printStackTrace();
}
}
#Test
//#Ignore
public void testFactoryInstanceWithoutRefl() {
Vehicle v1 = VehicleFactoryWithoutRefl.getInstance().newVehicle("car");
assertTrue(v1 instanceof Car);
}
}
Um... make it non-static? You can have instance initializer blocks too (same as static blocks, just without the static keyword). But test setup code should actually go into an explicit setUp() or #Before method.

How to handle a static final field initializer that throws checked exception

I am facing a use case where I would like to declare a static finalfield with an initializer statement that is declared to throw a checked exception. Typically, it'd look like this:
public static final ObjectName OBJECT_NAME = new ObjectName("foo:type=bar");
The issue I have here is that the ObjectName constructor may throw various checked exceptions, which I don't care about (because I'd know my name is valid, and it's allright if it miserably crashes in case it's not). The java compiler won't let me just ignore this (as it's a checked exception), and I would prefer not to resort to:
public static final ObjectName OBJECT_NAME;
static {
try {
OBJECT_NAME = new ObjectName("foo:type=bar");
} catch (final Exception ex) {
throw new RuntimeException("Failed to create ObjectName instance in static block.", ex);
}
}
Because static blocks are really, really difficult to read. Does anyone have a suggestion on how to handle this case in a nice, clean way?
If you don't like static blocks (some people don't) then an alternative is to use a static method. IIRC, Josh Bloch recommended this (apparently not in Effective Java on quick inspection).
public static final ObjectName OBJECT_NAME = createObjectName("foo:type=bar");
private static ObjectName createObjectName(final String name) {
try {
return new ObjectName(name);
} catch (final SomeException exc) {
throw new Error(exc);
}
}
Or:
public static final ObjectName OBJECT_NAME = createObjectName();
private static ObjectName createObjectName() {
try {
return new ObjectName("foo:type=bar");
} catch (final SomeException exc) {
throw new Error(exc);
}
}
(Edited: Corrected second example to return from method instead of assign the static.)
Your code is perfectly valid. I don't find it difficult to read. Other ways would only make it more worse. They're only difficult to read for starters, because most of them are not familiar with that. Just follow the standard conventions with regard to ordering of the elements in the code. E.g. do not put static initializers halfway or at the whole bottom of the code and also do not have multiple of them spreading over the class. Just put one at top, after static declarations.
static blocks aren't difficult to read. So I'd recommend that solution.
However, you can wrap your object in another object, for example
ObjectNameWrapper which shares an interface with your ObjectName, and whose constructor calls your ObjectName constructor, hiding all checked exceptions that occur. But again, I'd go for the static option.
You can use a method annotated with Lombok's #SneakyThrows
public static final ObjectName OBJECT_NAME = createObjectName();
#SneakyThrows(SomeException.class)
private static ObjectName createObjectName() {
return new ObjectName("foo:type=bar");
}
This annotation makes a checked exception behaves like an unchecked one.

Categories

Resources