I m having a problem of calling a constructor with arguments from default constructor.
Class A {
private static Properties properties;
A(Properties property){
// do some checks
try{
load(property, fileName)
} catch(IOException e) {
throw new RuntimeException();
}
}
A(){
this(load(properties));
}
private static Properties load(Properties properties, String fileName ) throws IOException {
try {
properties.load(A.class.getClassLoader()
.getResourceAsStream(fileName));
} catch (IOException ioException) {
throw new IOException("Unable to process the properties File. " + fileName, ioException);
}
return properties;
}
}
My problem is: In Default constructor I wanted to use try/catch block and do the same operation of throwing a run time exception. Can you help me out as what can be done in this?
WRT this post: chaining constructors in Java without throwing exceptions from the default constructor
I have an option of putting try/catch inside another method. But is there any other way?
P.S: I do not want to use 'throws'
Java does not allow chained constructor calls to be enclosed within a try block, since such constructs could if not restricted allow an object whose base object threw an exception to end up being returned to calling code. This makes it difficult to express certain concepts involving resources like files [e.g. it would be helpful to have a constructor open a file before chaining to the parent and close it afterward, but there's no way to safely have a constructor take responsibility for a file which is opened before chaining to the parent]. The best one can do in Java is avoid public constructors which might throw exceptions and instead use factory methods which can be better equipped to handle them.
Option 1: Pass the other constructor a new empty instance of Properties:
class A
{
public A()
{
this(new Properties());
}
// rest of code...
}
Option 2: Pass the other constructor a null instance of Properties. You'll then have to guard against null in load(...), but you probably should be anyway:
class A
{
public A()
{
this(null);
}
// rest of code...
}
Option 3: Pass the other constructor a default instance of Properties:
class A
{
private static final Properties defaultProperties;
static
{
defaultProperties = new Properties();
// populate here however you wish
}
public A()
{
this(defaultProperties);
}
// rest of code...
}
Related
I am writing a unit test for my below code
public class Class1 {
protected void execute(String a, String b) {
try{
process(a,b);
}
catch(Exception E){
Class2.write(e,Class1.class.getSimpleName())
}
}
private void process(String a, String b) {
validate(a,b);
// Doing some processing on a and b values
}
private void validate (String a, String b) {
if(a==null || a.isEmpty() || b==null || b.isEmpty())
throw new IllegalArgumentException("Input value cannot be null or empty");
}
}
For the above code, I am trying to write a UT which covers the exception use case. Below is my UT code,
#Test
public void test1(){
try {
PowerMockito.mockStatic(Class2.class);
PowerMockito.when(Class2.class, "write", Mockito.anyObject(), Mockito.anyString())
.thenCallRealMethod();
Class1 class1 = new Class1();
Class2.write(new IllegalArgumentException("Input value cannot be null or empty"),Class1.class.getSimpleClassName());
PowerMockito.verifyStatic(Class2.class, VerificationModeFactory.times(1));
class1.execute(Mockito.anyString(),Mockito.anyString());
} catch (Exception e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
}
I am getting the below exception when I execute the above test
Argument(s) are different! Wanted:
Class2.write{
java.lang.IllegalArgumentException:Input value cannot be null or empty,
Class1
}
Actual invocation has different arguments:
Class2.write{
java.lang.IllegalArgumentException:Input value cannot be null or empty,
Class1
}
Can someone please help me on resolving this issue?
I really appreciate your help and time
Thanks in Advance
Your Problem:
IllegalArgumentException does not use the string message for equality. It would be safer to test the string message or the class type. I would prefer that the test detect the type rather than the message, as the string message should not be used for control flow, it is an implementation detail.
System.out.println(Objects.equals(
new IllegalArgumentException(),
new IllegalArgumentException()));
// false
System.out.println(Objects.equals(
new IllegalArgumentException().getClass(),
new IllegalArgumentException().getClass()));
// true
So to mock this I would use matchers:
any(IllegalArgumentException.class), eq(Class1.class.getSimpleName())
Issues with your design:
I'm going to end with an argument against how this code is structured, being that it is not built around dependency injection. Rather than calling the static method Class2::write, you could be calling an instance method.
For example, create the interface:
public interface Writer {
void write(Exception e, String source);
}
You can now refactor the class to provide two ctors, one that accepts any writer, and one that defaults to Class2.
public class Class1 {
private final Writer writer;
public Class1() {
this(Class2::write);
}
public Class1(Writer writer) {
this.writer = writer;
}
protected void execute(String a, String b) {
try {
process(a,b);
}
catch (Exception E) {
writer.write(e, Class1.class.getSimpleName());
}
}
...
}
Using this strategy you can now simply create an instance mock of Writer. This avoids having to mock as static method which changes the bytecode of your application, and also make your class more flexible as it can support many different writer implementations now. Anything that is modifying the bytecode of the application should be used very sparingly, such as replacing static method calls, does not truly validate the runtime execution of your code.
In my opinion, the majority of the PowerMockito/PowerMock only help verify code which was not built with testability / flexibility in mind. You shouldn't need to use anything outside of the Mockito/EasyMock tool-set for well structured code. There are some exceptions but the tool-set should be used very sparingly.
I am having troubles while trying to refactor exception handling logic in an helper class.
My code uses a repository which accesses a database and might throw the custom exception RepositoryException. If such exception is thrown by the repository, I want my code to catch it and set an error label in the graphical user interface (view):
... // more code
try {
existingCourse = repository.findByTitle(course.getTitle()); // <- throws RepositoryException
} catch (RepositoryException e) {
view.showError(e.getMessage(), course);
return;
}
... // some more code
The point is that this code is repeated several times and I would prefer to have it refactored in an helper class.
This is what I came up to after some experiments:
A custom FunctionalInterface called ThrowingSupplier, which represent the code that throws the exception.
A TransactionManager helper class, with a catcher methods that accepts a ThrowingSupplier
This is the related code (BaseEntity is just a base class for entities in my domain, as you might guess):
// ThrowingSupplier.java
#FunctionalInterface
public interface ThrowingSupplier<T extends BaseEntity> {
T get() throws RepositoryException;
}
/* ------------------------------------------------------ */
// ExceptionManager.java
public final class ExceptionManager<T extends BaseEntity> {
private T result;
private String exceptionMessage;
ExceptionManager() {
}
public boolean catcher(ThrowingSupplier<T> supplier) {
try {
clearResult();
clearExceptionMessage();
result = supplier.get();
return true;
} catch (RepositoryException e) {
exceptionMessage = e.getMessage();
}
return false;
}
// public getters and 'clearers' for attributes
...
}
And this is how I am using this now:
...
em = new ExceptionManager();
... // more code
if (!em.catcher(() -> repository.findByTitle(course.getTitle()))) {
view.showError(em.getExceptionMessage(), course);
return;
}
existingCourse = em.getResult();
... // some more code
Now it seems to me that this does not give any advantages with respect to using directly the try catch in every repository invocation. This is mainly because I need both the return value of the repository method and a way to tell the caller if the repository call has been successful. As a variation I tried to add the showError call inside catcher, but then I must pass view and entity in every invocation of catcher, which I do not like very much as it makes the code less readable.
Is there another way to accomplish this in an elegant manner or it is better to leave the try catch in every call to the repository? Also, what is the standard way to deal with this problem?
This question already has answers here:
Can we call a static method with a null object in Java? If so, how?
(4 answers)
Closed 4 years ago.
I have the following class, which is used for controlling some debugging and beta testing options in various places in my Android app. It just contains some flags and some logic to (de)serialize it to/from JSON.
public class DevConfiguration {
public boolean dontSendSMS;
public static String toJsonString(DevConfiguration devConfiguration) {
JSONObject json = new JSONObject();
if( devConfiguration != null ) {
try {
json.put("dontSendSMS", devConfiguration.dontSendSMS);
} catch (JSONException e) {
e.printStackTrace();
}
}
return json.toString();
}
public static DevConfiguration fromJsonString(String jsonString) {
if( jsonString.isEmpty() )
return null;
DevConfiguration result = new DevConfiguration();
try {
JSONObject jsonObj = new JSONObject(jsonString);
result.dontSendSMS = jsonObj.optBoolean("dontSendSMS", false);
} catch (JSONException e) {
e.printStackTrace();
}
return result;
}
}
Now, in one of my services I receive a serialized DevConfiguration object in an Intent, and might later pass it on to another service:
serviceIntent.putExtra("dev_conf", DevConfiguration.toJsonString(mDevConfiguration));
I choose to make the toJsonString() method static, so that I don't risk invoking it on a null instance. However, it's still possible to make a mistake somewhere and invoking the static method on an instance - potentially a null instance!
mDevConfiguration.toJsonString(mDevConfiguration);
There is a Lint warning in Android Studio, but still it's a potential NullPointerException bug waiting to happen. I thought it might be possible to hide it by defining a similar private method but with a different signature
/** Hide instance implementation **/
private String toJsonString(Object o){ return ""; }
but of course calling it with a DevConfiguration parameter will invoke the static method anyway, and the IDE doesn't give any more warnings than before either.
Is there any way to "hide" the static method from instance variables?
EDIT
Comments make it clear that invoking a static method on a null instance is perfectly legal. However, the question is not "How do I prevent a NullPointerException when invoking a static method on a null instance?", but the more general "How can I prevent invoking a static method on an instance of my class?".
In other words - is there any way to prevent the compiler from compiling if one accidentally tries to invoke a static method on an instance?
Calling a static method on a variable with null value will not raise NullPointerException. Following code will print 42 even though variable i is null.
public class Test {
public static void main(String... args) {
Integer i = null;
System.out.println(i.parseInt("42"));
}
}
When calling static methods by variable, what really matters is the declared type of the variable and not the referenced type of its value. This is related to the fact that static methods in java are not polymorphic.
„How can I prevent invoking a static method on an instance of my class?"
Calling static methods by variable is just a regular language feature defined in the Java spec. I’d be surprised if there were any method to suppress it in general.
If I had to do it for a selected class, I would probably migrate static methods to a separate „companion” utility (as described in another answer).
But having such static (factory) methods in your class is a perfectly fine idiom (see for example: Joshua Bloch, „Effective Java”, Item 1: Consider static factory methods instead of constructors). I wouldn’t easily give up on it.
I see a few ways you could do this:
Use a Utils class:
public class Utils {
public static String toJsonString(DevConfiguration devConfiguration) {
JSONObject json = new JSONObject();
if( devConfiguration != null ) {
try {
json.put("dontSendSMS", devConfiguration.dontSendSMS);
} catch (JSONException e) {
e.printStackTrace();
}
}
return json.toString();
}
public static DevConfiguration fromJsonString(String jsonString) {
if( jsonString.isEmpty() )
return null;
DevConfiguration result = new DevConfiguration();
try {
JSONObject jsonObj = new JSONObject(jsonString);
result.dontSendSMS = jsonObj.optBoolean("dontSendSMS", false);
} catch (JSONException e) {
e.printStackTrace();
}
return result;
}
}
Now you can just makes calls to Utils.method() and avoid confusion.
Use Kotlin
Kotlin actually makes it really hard (if not impossible) to call a static method on a dynamic receiver. It won't show in the method suggestions, and will underline in red if you type it manually. It might not even compile, although I haven't gotten that far.
Kotlin also has built-in null protection: instance?.method(). The ? means method() just won't execute if instance is null.
Just don't call a static method on a dynamic receiver. If you do it by accident, go back and fix it. You shouldn't be relying on Java to work around your syntax errors for you.
Finally, why even do this? I highly doubt mDevConfiguration is ever null, unless you initialize it in a really weird spot. If it is, you may want to look at reorganizing your code. Because, again, you shouldn't be relying on Java to work around your syntax errors for you. Also, if it is null, it won't throw an NPE, at least in Java, since it doesn't need a dynamic receiver to run (this is probably different in Kotlin).
It's up to you to make code that works as it should, and implement the proper null checks, error handling, etc. If you miss something, it's no big deal; that's why you test your code and fix the crashes and bugs you catch before you release it. Anything you don't catch will be reported by the Google Play Console (if you publish there) or Firebase (if you implement that) or your users.
Sorry if the above sounds harsh, but I'm really having trouble seeing why you'd want to do this instead of just checking your code.
If you really want to keep this structure, at least make the constructor for DevConfiguration private:
public class DevConfiguration {
//...
private DevConfiguration() {}
//...
}
That way, only the static methods inside it can create an instance.
Description:
I am always told by people check all your parameters all the time which results in a lot of if checks and try catches.
Question:
In the code below I cleaned the code such that only method that handles the exception handling is at the root method that is exposed publicly and not in the refactored private helper methods. Is this practice ok?
I'm not handling exceptions closer to the methods they could occur in but the code is much cleaner.
Code Notes:
Method validateInputs() not included.
ParameterObject a is derived let say from parameters created through "someCode", it represents parameters I want to pass around. Anytime I have a need for more than 2 parameters i refactor those parameters to a parameter object.
Code:
public class UnderTest {
public UnderTest() {}
public boolean runWork( String someValue ) throws CustomException
{
try
{
validateInputs();
// someCode
.
.
processWork( ParameterObject a );
}
catch( Exception e )
{
logError(e);
}
}
private void processWork( ParameterObject a )
{
Operation1( ParameterObject a );
Operation2( ParameterObject a );
}
private void Operation1( ParameterObject a )
{
// someCode
}
private void Operation2( ParameterObject a )
{
// someCode
}
private void logError(Exception e)
{
throw new CustomException(e,"Message");
}
}
I tend to check arguments when they enter the class by some public API. In private methods I check only by assertions or not at all. This implies that I trust my own class a bit more.
I would opt for a bit of both. Validating inputs is always a good idea and libraries such as the Apache commons-lang Validate class can make this easier. Generally speaking, an incorrect argument should cause a runtime exception (usually IllegalArgumentException or NullPointerException). How deeply you go into your private methods to do input validation is a matter of taste. Remember that the sooner you spot an invalid argument, the more helpful the error message is going to be.
Of course, this assumes you document your public facing APIs well (and ideally your internal methods too). Make it clear what is valid for your inputs.
My objective is to have a private static Properties object in my class, to act as defaults when creating other Properties objects needed by my application. The current implementation looks like this:
public class MyClass {
private static Properties DEFAULT_PROPERTIES = new Properties();
static {
try {
DEFAULT_PROPERTIES.load(
MyClass.class.getResourceAsStream("myclass.properties"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Looking at it, it works, but it doesn't feel right.
How would you do it?
There are basically two ways. First way is using the static block as you have shown (but then with an ExceptionInInitializerError instead of the RuntimeException). Second way is using a static method which you call immediately on declaration:
private static Properties DEFAULT_PROPERTIES = getDefaultProperties();
private static Properties getDefaultProperties() {
Properties properties = new Properties();
try {
properties.load(MyClass.class.getResourceAsStream("myclass.properties"));
} catch (IOException e) {
throw new ConfigurationException("Cannot load properties file", e);
}
return properties;
}
The ConfigurationException can just be your custom class extending RuntimeException.
I personally prefer the static block because it doesn't make sense having a method which is executed only once ever in its life. But if you refactor the method so that it takes a filename and can be reused globally, then that would be more preferred.
private static Properties DEFAULT_PROPERTIES = SomeUtil.getProperties("myclass.properties");
// Put this in a SomeUtil class.
public static Properties getProperties(String filename) {
Properties properties = new Properties();
try {
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(filename));
} catch (IOException e) {
throw new ConfigurationException("Cannot load " + filename, e);
}
return properties;
}
Instead of a generic RuntimeException, I would throw an ExceptionInInitializerError, which is ment for exacctly this purpose. From the API documentation: "Signals that an unexpected exception has occurred in a static initializer."
Seems acceptable to me; load in the static initialiser, it gets called only when the class is referenced, and is only called once. I like it. The only thing I'd do is make it final.
Well, aside from the exception. I'd try and avoid that somehow (I have in the back of my mind that you should avoid exceptions in those types of initialisers, but I could be wrong on that).