Handling null values where not allowed - java

I have the following code in the mClass constructor:
public mClass(Context ctx) {
super();
this.ctx = ctx;
}
The context can't be null because its necesary for the object operation. So if I allow the creation of an new mClass(null) it will break later.
I'd like to crash when the object is create because is when the incorrect situation is happening. Whats the standard way of doing this?
For example making
public mClass(Context ctx) {
super();
if(ctx==null) throw new Exception ("....");
this.ctx = ctx;
}
forces to declare the method as exception thrower and I dont wan't to do this because passing a null value is not usual

Throw java.lang.IllegalArgumentException,
which is a runtime exception so you don't need to forcibly handle this, and if it is thrown application will get crashed (if it is not handled)

You can avoid throwing an exception from the constructor all together by making your class' constructor private thereby ensuring clients can only create instances of your class via a builder. The builder can check the validity of the supplied constructor dependencies before constructing an object as shown below:
public class MyClass {
public static class MyClassBuilder {
private Context ctx;
public MyClassBuilder setContext(Context ctx) {
this.ctx = ctx;
return this;
}
public MyClass build() {
if(ctx==null) {
throw new IllegalArgumentException ("");
} else {
return new MyClass(this.ctx);
}
}
}
private final Context ctx;
private MyClass(Context ctx) {
super();
this.ctx = ctx;
}
}

If MyClass cannot be responsible for constructing its own Context you should inject it like you do. Throwing a RuntimeException or any subclass will do for a null-check, but IllegalArgumentException is most appropriate here.
Do not forget to make the ctx field final, it will make your code more robust.

Related

Run a list of classes in parallel which implement the same interface in java

I have created the below mentioned base and derived class
public abstract class ContextBase {
private String customerID;
private String marketplaceID;
}
public class ReturnContext extends ContextBase {
private String returnID;
}
Then I created an interface which has a method called perform and some classes which implements this interface
public interface ValidatorInterface<T extends ContextBase> {
CompletableFuture<List<String>> perform(T context);
}
public class AlphaValidator implements ValidatorInterface<ContextBase> {
#Override
public CompletableFuture<List<String>> perform(ContextBase contextBase) {
....
}
}
public class BetaValidator implements ValidatorInterface<ReturnContext> {
#Override
public CompletableFuture<List<String>> perform(ReturnContext context) {
....
}
}
I want to run a list of classes which implements the ValidatorInterface in parallel, So I created a ValidatorRunner class
public class ValidatorRunner<T extends ContextBase> {
public List<String> runValidators(final T context,
final List<ValidatorInterface<T>> validatorsList) {
final Map<String, CompletableFuture<List<String>>> futureAggregatedProblems = new LinkedHashMap<>(validatorsList.size());
List<String> problems = new ArrayList<>();
validatorsList.forEach(validator -> runValidator(
validator, futureAggregatedProblems, context));
futureAggregatedProblems.forEach((validatorName, futureProblems) -> {
try {
problems.addAll(futureProblems.get(FUTURE_TIMEOUT_MS, TimeUnit.MILLISECONDS));
} catch (InterruptedException | ExecutionException | CompletionException | TimeoutException ex) {
// TODO Do not ignore InterruptedException
throw new InternalServiceException("Error executing validators : " + ex.getMessage(), ex);
}
});
return problems;
}
private void runValidator(final ValidatorInterface<T> validator,
final Map<String, CompletableFuture<List<String>>> futureAggregatedProblems,
final T context) {
futureAggregatedProblems.put(validator.getClass().getCanonicalName(), validator.perform(context));
}
This implementation does seem to work when I do this
ValidatorRunner<ReturnContext> validatorRunner = new ValidatorRunner<ReturnContext>();
ReturnContext context = new ReturnContext();
BetaValidator beta = new BetaValidator();
List<ValidatorInterface<ReturnContext>> validatorList = new ArrayList<>();
validatorList.add(beta);
List<String> problems = validatorRunner.runValidators(context, validatorList);
The problem is that AlphaValidator is implemented on base type (ContextBase) while BetaValidator is implemented on derived type (ReturnContext). I want to run AlphaValidator and BetaValidator in parallel while passing an instance of ReturnContext as context. How it can be achieved ?
EDIT 1
The reason I created ValidatorInterface as T extends ContextBase because I want each validator to use either a ContextBase or a derived class of ContextBase.
I have created AlphaValidator on base type ContextBase because I want the AlphaValidator to be created and executed using any of the derived class of ContextBase. While BetaValidator is created on ReturnContext because I want the BetaValidator to be created and executed using ReturnContext only.
Lets suppose I create a new derived class called ReplacementContext which extends ContextBase and also a new validator called as GammaValidator on derived type ReplacementContext. I want to be able to run AlphaValidator and GammaValidator using ReplacementContext. AlphaValidator and BetaValidator should run on ReturnContext. But I dont want to run BetaValidator and GammaValidator in parallel because they serve different purpose and separate contexts (thats why they are created on separate contexts, ReturnContext and ReplacementContext respectively).
Problem with the above code
When providing a single concrete context for multiple validators each validator MUST support the given context class. This is a design issue.
My solution
An alternative solution is to provide multiple contexts to the runValidate method where each context can placed next to the correct validators.
Given my example the ContextProcessor.of() will take care that the compiler only allows correct assignments for validators and contexts.
I suggest to change your ValidatorRunner to a similar version to this code:
public class ValidatorRunner {
static class ContextProcessor<T extends ContextBase> {
private final List<ValidatorInterface<T>> validators;
private final T context;
private ContextProcessor(List<ValidatorInterface<T>> validators, T context) {
this.validators = validators;
this.context = context;
}
public static <V extends ValidatorInterface<C>, C extends ContextBase> ContextProcessor<C> of(List<V> validators, C context) {
//noinspection unchecked
return new ContextProcessor<>((List<ValidatorInterface<C>>) validators, context);
}
public List<ValidatorInterface<T>> getValidators() {
return validators;
}
public T getContext() {
return context;
}
}
public List<String> runValidators(final List<ContextProcessor<? extends ContextBase>> processors) {
var validators = processors.stream().map(p -> p.validators.size()).reduce(Integer::sum).orElse(0);
var latch = new CountDownLatch(validators);
var problemStack = new ArrayList<String>();
//noinspection unchecked
processors.forEach(p -> p.getValidators().forEach(validator ->
runValidator((ValidatorInterface<ContextBase>) validator, p.getContext())
.orTimeout(10_000L, TimeUnit.MILLISECONDS)
.thenAccept(problems -> {
problemStack.addAll(problems);
latch.countDown();
})
));
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return problemStack;
}
private CompletableFuture<List<String>> runValidator(final ValidatorInterface<ContextBase> validator, final ContextBase context) {
return validator.perform(context);
}
public static void main(String[] args) {
var problems = new ValidatorRunner().runValidators(
List.of(
ContextProcessor.of(List.of(new AlphaValidator(), new AlphaValidator()), new ReplacementContext()),
ContextProcessor.of(List.of(new AlphaValidator()), new ContextBase() {}),
ContextProcessor.of(List.of(new BetaValidator(), new BetaValidator()), new ReturnContext())
)
);
System.out.println(problems);
}
}
When running the provided main method, the following result is expected:
[error within context ReplacementContext, error within context ReplacementContext, error within context , error within context ReturnContext, error within context ReturnContext]
Where every validator has returned the Future String "error within context" + context.getClass().getSimpleName()
Maybe this will help you find a way to solve your problem.

Problems about Cglib proxy MethodInterceptor callback parameters

When using Spring Cglib proxy, we need to implement a MethodInterceptor callback, I have some problems about this callback. To make it clearer, let's use a simple example.
Here is my target class MyPlay.java
public class MyPlay {
public void play() {
System.out.println("MyPlay test...");
}
}
And I created a callback:
public class CglibMethodInterceptor implements MethodInterceptor {
private Object target;
public CglibMethodInterceptor(Object target) {
this.target = target;
}
public Object getProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
#Override
public Object intercept(
Object o,
Method method,
Object[] objects,
MethodProxy methodProxy) throws Throwable {
System.out.println("CGLIB prep work...");
Object obj = method.invoke(target, objects);
System.out.println("CGLIB post work...");
return obj;
}
}
In my Main class:
MyPlay myPlay = new MyPlay();
cglibMethodInterceptor = new CglibMethodInterceptor(myPlay);
Play myPlayProxy = (Play) cglibMethodInterceptor.getProxy();
myPlay.play();
myPlayProxy.play();
I'm confused about the meaning of the parameters of the intercept method:
#Override
public Object intercept(
Object o,
Method method,
Object[] objects,
MethodProxy methodProxy) throws Throwable {
}
So, I set up a breakpoint to at the myPlayProxy.play() and step into it. I took a screenshot:
Problem: What are the method and methodProxy parameters? What is the difference between them? When I use the methodProxy to invoke, it also works, which confuses me.
Object obj = method.invoke(target, objects);
// This also works, why?
// Object obj = methodProxy.invoke(target, objects);
The Javadoc says:
The original method may either be invoked by normal reflection using the Method object, or by using the MethodProxy (faster).
I don't know what makes it faster.

Converting C# to Java. Calling newInstance() of generic class' constructor always returns NullPointerException

I'm fairly new to Java. I am trying to port code from C# and I am having issues with creating an instance of a generic class but I keep getting NullPointerExceptions. Been on this for a while and need another set of more experienced eyes.
Here is the C# version:
public static T CreateInstance<T>(WebdriverContext context) where T : WebSiteControl
{
//If type has constructor with 1 parameter and is type IContext. Then use that.
//Else use default constructor.
var type = typeof(T);
//First constructor attempt.
var ctor = type.GetConstructor(new[] { context.GetType() });
if (ctor != null)
{
var ctrl = (T)ctor.Invoke(new object[] { context });
return ctrl;
}
//Second constructor attempt.
ctor = type.GetConstructor(Type.EmptyTypes);
if (ctor != null)
{
var ctrl = (T)ctor.Invoke(new object[] { });
ctrl.WebContext = context;
return ctrl;
}
throw new Exception("No appropriate constructors found for " + type.Name);
}
This works as intended.
Java version is as follows:
public static <T extends WebSiteControl> T CreateInstance (Class<T> clazzType, WebdriverContext context) throws Exception{
//If type has constructor with 1 parameter and is type IContext. Then use that.
//Else use default constructor.
Constructor ctor = clazzType.getSuperclass().getConstructor(new Class[] {context.getClass()});
//First constructor attempt.
if (ctor != null)
{
T ctrl = (T)ctor.newInstance(new Object[] {context});
return ctrl;
}
//Second constructor attempt.
ctor = clazzType.getSuperclass().getConstructor(ctor.getClass());
if (ctor != null)
{
T ctrl = (T) ctor.newInstance(new Object[] { });
ctrl.WebContext = context;
return ctrl;
}
throw new Exception("No appropriate constructors found for " + clazzType.toString()+".");
}
This works all as it should until I get to the line
T ctrl = (T)ctor.newInstance(new Object[] {context});
Any time I try to use newInstance() in any form it throws the NullPointerException.
ErrorMessage.img
I feel like I am missing something super obvious.
Anyone know what I've missed?
Since the NullPointerException is wrapped in an InvocationTargetException, the actual source has to lie somewhere in the constructor that is called, according to Oracle Docs:
Throws: InvocationTargetException - if the underlying constructor throws an exception.
The code you posted seems fine.
Unrelated detail: getConstructor() doesn't return null if no Method was found but throws an exception, so your second attempt will never be reached.
Fixed it! #MDK gave me the idea to look through the initialization of my other classes. Turns out in WebsiteControl I was setting up a variable on initialization which depended on another one which was only ever set in the constructor.
private WebdriverContext Webcontext;
private Webdriver driver = Webcontext.getDriver();
public WebSiteControl(WebdriverContext context){
WebContext = context;
webdriver = WebContext.getDriver();
}
I was mixing my logic with C# where you can make a variable with a {get, private set}.
Fixed by adding webdriver = WebContext.getDriver(); to every constructor (not ideal, but hey) and not initializing the driver first:
private WebdriverContext Webcontext;
private Webdriver driver;
public WebSiteControl(WebdriverContext context){
WebContext = context;
webdriver = WebContext.getDriver();
}

Difference between volatile Boolean and Boolean

Suppose I declare like this:
private static Boolean isCondition = false;
Then I am using this like below in synchronized statement:
synchronized(isCondition){
isCondition = true;
somestuff();
}
Here my question is if I update isCondition then it will get a new reference due to autoboxing and if new thread will come in synchronized block then they will get lock on new object enter into synchronized block. This I dont want to happen.
So please suggest me alternatives and if I use volatile then how exactly it will prevent this like below:
private static volatile Boolean isCondition = false;
The actual code is like that:
package com.test.spring.utils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* #author Pratik
*/
public class TouchPointsSpringContext implements ApplicationContextAware
{
private static final Log g_log = LogFactory.getLog(TouchPointsSpringContext.class);
private static ApplicationContext CONTEXT;
private static volatile Boolean isServiceInitialized = false;
/**
* This method is called from within the ApplicationContext once it is done
* starting up, it will stick a reference to itself into this bean.
*
* #param context
* a reference to the ApplicationContext.
*/
public void setApplicationContext(ApplicationContext context) throws BeansException
{
CONTEXT = context;
}
private static void initializeTouchPointService()
{
g_log.info("getting touchpoints service application context");
String[] locations =
{ "appContext-main.xml", "appContext-hibernate.xml" };
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(locations);
g_log.info("setting touchpoints service application context");
CONTEXT = applicationContext;
}
/**
* This is about the same as context.getBean("beanName"), except it has its
* own static handle to the Spring context, so calling this method
* statically will give access to the beans by name in the Spring
* application context. As in the context.getBean("beanName") call, the
* caller must cast to the appropriate target class. If the bean does not
* exist, then a Runtime error will be thrown.
*
* #param beanName
* the name of the bean to get.
* #return an Object reference to the named bean.
*/
public static Object getBean(String beanName)
{
if (!isServiceInitialized || (CONTEXT == null))
{
synchronized (isServiceInitialized)
{
if (!isServiceInitialized)
{
initializeTouchPointService();
isServiceInitialized = true;
}
}
}
return CONTEXT.getBean(beanName);
}
public static void main(String[] args)
{
TouchPointsSpringContext.getBean("lookupService");
}
}
Using a Boolean as a lock is a very bad idea: you are effectively using a global variable Boolean.TRUE/FALSE which any other parts of your code can access and potentially deadlock your code.
And using a non final variable as a lock is an even worse idea: everytime you reallocate the instance (isCondition = true) you change your lock, meaning that two threads may execute your synchronized block concurrently, which kind of defeats the whole idea.
So I would recommend a standard idiom:
private static final Object lock = new Object();
private static boolean isCondition;
synchronised(lock) {
isCondition = true;
// ...
}
I think most of the other answers here are not completely right. It is a little bit difficult to understand what you are doing because you do not include the code for initializeTouchPointService, however you appear to be doing something which is a variation on the "Double Checked Locking" idiom.
It is difficult to get this concurrency idiom right and if you are using a version of Java before 5, then you should not attempt to use this idiom at all. I will assume you are using Java 5+.
The important parts of your code are:
private static ApplicationContext CONTEXT;
private static volatile Boolean isServiceInitialized = false;
...
if (!isServiceInitialized || (CONTEXT == null))
{
synchronized (isServiceInitialized)
{
if (!isServiceInitialized)
{
initializeTouchPointService();
isServiceInitialized = true;
}
}
}
Assuming that you are using Java 5 or above, you must use volatile on all relevant variables to get this idiom to work correctly. You must also re-check the full condition inside the synchronized block.
You must not use a Boolean as your lock, since Boolean objects are immutable you will get a different object when you change the condition from false to true. Instead use a separate lock object and boolean primitive for the condition.
private final Object lock = new Object();
private volatile boolean isServiceInitialized;
private volatile ApplicationContext context;
public Object getBean(String beanName) {
if (!isServiceInitialized || context == null) {
synchronized(lock) {
if (!isServiceInitialized || context == null) {
initializeTouchPointService();
isServiceInitialized = true;
}
}
}
return CONTEXT.getBean(beanName);
}
However, locks in recent versions of Java have very good performance on most architectures. So using the double-checked locking idiom may not make your program much faster - especially compared to how slow spring reflection will be when calling getBean.
Instead of your double-checked design, how about the following simpler design which also avoids volatile:
private final Object lock = new Object();
private boolean isServiceInitialized;
private ApplicationContext context;
private ApplicationContext context() {
synchronized(lock) {
if (!isServiceInitialized || context == null) {
initializeTouchPointService();
condition = true;
}
return context;
}
}
public Object getBean(String beanName) {
return context().getBean(beanName);
}
I also recommend avoiding the use of static where ever possible, as writing unit tests in the presence of global variables can be tricky. I would seriously consider if there is any way you can change your design to reduce or eliminate your use of static state.
============ edit
Based on my best guess of what the OP is trying to achieve, perhaps this would be better. However, it removes the lazy initialisation. So if you program sometimes refers to this TouchPointsSpringContext class without using the getBean() method then you don't want this answer.
public class TouchPointsSpringContext
{
private static final Log g_log = LogFactory.getLog(TouchPointsSpringContext.class);
private static ApplicationContext CONTEXT = initializeTouchPointService();
private static ApplicationContext initializeTouchPointService()
{
g_log.info("getting touchpoints service application context");
String[] locations =
{ "appContext-main.xml", "appContext-hibernate.xml" };
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(locations);
g_log.info("setting touchpoints service application context");
return applicationContext;
}
public static Object getBean(String beanName)
{
return CONTEXT.getBean(beanName);
}
public static void main(String[] args)
{
TouchPointsSpringContext.getBean("lookupService");
}
}
Note that the JVM will automatically make sure that your static CONTEXT gets initalised exactly once.
Or alternatively, if you can avoid implementing "ApplicationContextAware" (implementing it seems unnecessary given the rest of the code), but you need to keep he lazy initialisation, then this might be better:
public class TouchPointsSpringContext
{
private static final Log g_log = LogFactory.getLog(TouchPointsSpringContext.class);
private static volatile ApplicationContext CONTEXT;
private static final Object lock = new Object();
private static ApplicationContext initializeTouchPointService()
{
g_log.info("getting touchpoints service application context");
String[] locations =
{ "appContext-main.xml", "appContext-hibernate.xml" };
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(locations);
g_log.info("setting touchpoints service application context");
return applicationContext;
}
public static Object getBean(String beanName)
{
if (CONTEXT == null)
{
synchronized (lock)
{
if (CONTEXT == null)
{
CONTEXT = initializeTouchPointService();
}
}
}
return CONTEXT.getBean(beanName);
}
public static void main(String[] args)
{
TouchPointsSpringContext.getBean("lookupService");
}
}
Not a full answer, but: Several people here said things like "You must not use Boolean as a lock because..."
Those explanations complicate what should be a simple idea. When you write synchronized (foo) { ... }, you are not synchronizing on the variable foo, you are synchronizing on some object that is the result of the expression, foo.
You did something like this in your example:
Boolean isCondition = ...;
synchronized(isCondition) {
isCondition = true;
...
}
When a thread enters that synchronized block, it acquires the monitor for a particular instance of the Boolean class. Then, the next thing that it does is assign isCondition. The same variable now points to a different instance.
When a second thread tries to enter the same block, it will attempt to synchronize on the new instance, and it will succeed even if the first thread still is in the block. The only thing that synchronized prevents is, it prevents two different threads from synchronizing on the same instance at the same time. In your example, the two different threads synchronized on two different instances, and that is allowed.
Never do this:
synchronized ( foo ) {
...
foo = ...;
...
}
A good practice is, if you are going to put a simple variable name in the parens (and that's by far the most common use-case), then make it a final variable.
final MyThingummie myThingummie = new MyThingummie(...);
synchronized ( myThingummie ) {
...
}
As some others have suggested in comments, you could synchronize on something else and avoid this problem.
Define a new variable to lock on:
private final Object lock;
Now change your code a bit:
synchronized(lock) {
isCondition = true;
somestuff();
}
You can also achieve similar functionality without the variable by having all of this in a synchronized method.

Is the following utility class thread-safe?

First let's look at the utility class (most javadoc has been removed to simply the example):
public class ApplicationContextUtils {
/**
* The application context; care should be taken to ensure that 1) this
* variable is assigned exactly once (in the
* {#link #setContext(ApplicationContext)} method, 2) the context is never
* reassigned to {#code null}, 3) access to the field is thread-safe (no race
* conditions can occur)
*/
private static ApplicationContext context = null;
public static ApplicationContext getContext() {
if (!isInitialized()) {
throw new IllegalStateException(
"Context not initialized yet! (Has the "
+ "ApplicationContextProviderBean definition been configured "
+ "properly and has the web application finished "
+ "loading before you invoked this method?)");
}
return context;
}
public static boolean isInitialized() {
return context == null;
}
#SuppressWarnings("unchecked")
public static <T> T getBean(final String name, final Class<T> requiredType) {
if (requiredType == null) {
throw new IllegalArgumentException("requiredType is null");
}
return (T) getContext().getBean(name, requiredType);
}
static synchronized void setContext(final ApplicationContext theContext) {
if (theContext == null) {
throw new IllegalArgumentException("theContext is null");
}
if (context != null) {
throw new IllegalStateException(
"ApplicationContext already initialized: it cannot be done twice!");
}
context = theContext;
}
private ApplicationContextUtils() {
throw new AssertionError(); // NON-INSTANTIABLE UTILITY CLASS
}
}
Finally, there is the following helper Spring managed bean that actually calls the 'setContext' method:
public final class ApplicationContextProviderBean implements
ApplicationContextAware {
public void setApplicationContext(
final ApplicationContext applicationContext) throws BeansException {
ApplicationContextUtils.setContext(applicationContext);
}
}
Spring will call the setApplicationContext method once after the app is started. Assuming a nincompoop has not previously called ApplicationContextUtils.setContext(), that should lock in the reference to the context in the utility class, allowing calls to getContext() to success (meaning that isInitialized() returns true).
I just want to know if this class violates any principles of good coding practices, with respect to thread safety in particular (but other stupidities found are welcome).
Thanks for helping me to become a better programmer, StackOverflow!
Regards,
LES
P.S. I didn't go into why I need this utility class - let it suffice that I indeed do have a legitimate need to access it from a static context anywhere in the application (after the spring context has loaded, of course).
No. It's not thread safe.
Writes to the context class variable are not guaranteed to be visible to threads that read that variable through getContext().
At the very least, declare context to be volatile. Ideally, redefine context as an AtomicReference, set through a call like this:
if(!context.compareAndSet(null, theContext))
throw new IllegalStateException("The context is already set.");
Here's a more complete example:
public class ApplicationContextUtils {
private static final AtomicReference<ApplicationContext> context =
new AtomicReference<ApplicationContext>();
public static ApplicationContext getContext() {
ApplicationContext ctx = context.get();
if (ctx == null)
throw new IllegalStateException();
return ctx;
}
public static boolean isInitialized() {
return context.get() == null;
}
static void setContext(final ApplicationContext ctx) {
if (ctx == null)
throw new IllegalArgumentException();
if (!context.compareAndSet(null, ctx))
throw new IllegalStateException();
}
public static <T> T getBean(final String name, final Class<T> type) {
if (type == null)
throw new IllegalArgumentException();
return type.cast(getContext().getBean(name, type));
}
private ApplicationContextUtils() {
throw new AssertionError();
}
}
Note that in addition to thread safety, this also provides type safety, taking advantage of the Class instance passed into the getBean() method.
I'm not sure how you plan to use the isInitialized() method; it doesn't seem very useful to me, since as soon as you call it, the condition could change, and you don't have a good way to be notified.
Spring already has a class called ContextSingletonBeanFactoryLocator that wires up static access to the ApplicationContext for you. At the least, using this class might save you the trouble of having to worry about if your custom approach is thread safe.
However it's a little confusing to use this class at first, since there's a little bit of indirection going on. You can take a look at this blog post for more information on how this call works.

Categories

Resources