How to combine 2 different annotated methods into a pointcut? - java

I want to annotated 2 different methods and related them together in order to match the global variable and method which uses it
#FirstAnn(funcName = "foo")
def foo = {
val value = boo()
val checkValue = value > 2
return checkValue
}
#SecondAnn(funcName = "foo", paramName = "value")
def boo : Double = {
return B.getValue
}
#Pointcut("execution(* *(..)) && #annotation(firstAnn) && if()")
public static boolean execute(FirstAnn firstAnn){
return true;
}
#Pointcut("execution(* *(..)) && #annotation(secAnn) && if()")
public static boolean execute2(SecondAnn secAnn){
return true;
}
#Before("execute(firstAnn) && execute2(secAnn)")
public void before(FirstAnn firstAnn, SecondAnn secAnn, JoinPoint.StaticPart jps,JoinPoint jp){
if (firstAnn.funcName == secAnn.funcName){
print("value X is used in funcname Y" ) //here I will retrieve the value from signature like: value 3 is used in function foo
}
}
But the code doesn't get to this place...Any suggestion to make it work please?
thanks

Your usage of && implies you expect both methods to be executed at the same time. But of course they are not. Either the first or the second one is matched, they are two different joinpoints, thus combining the pointcuts with && will never make your advice method fire. You need to use || instead to match either one.
Looking at your source code, what you probably want is to trigger the advice when boo is called from within foo and possibly also the other way around. You are also trying to bleed context from the calling method into the called method. This is called a wormhole pattern, see also my answers here:
https://stackoverflow.com/a/12130175/1082681
https://stackoverflow.com/a/50577287/1082681
https://stackoverflow.com/a/25075051/1082681
So probably you want to use a pointcut like
execute2(secAnn) && cflow(execute(firstAnn))
for your example or the other way around if you have cases where the second method calls the first one:
cflow(execute2(secAnn)) && execute(firstAnn)

Related

Multi threaded issue with myMethod()

I came across this question and I am trying to figure out the answer.
This is the question:
Assuming a threaded environment, and without knowing anything else, what is the potential problem with myMethod()? How can we fix it in the simplest way?
What is the issue with myMethod?
public class DummyTest {
private static final String FUBAR = "fubar";
public boolean myMethod(final MyObject bar) {
if (bar.getFoo() != null) {
return bar.getFoo().equals(FUBAR);
} else {
return false;
}
}
public interface MyObject {
String getFoo();
void setFoo(String o);
}
}
You are checking bar.getFoo() twice which in multi threaded environment can have different results. MyObject is an interface which its methods can be not synchronized .
You also need to add null check for bar and you don't need null check for bar.getFoo() if you change you code (see below)
You can replace with one liner method:
return bar != null && FUBAR.equals(bar.getFoo());
Or with ternary conditional operator
return bar == null ? false : FUBAR.equals(bar.getFoo());
(In addition to bar potentially being null).
Potentially, bar.getFoo() could return different values on multiple invocations.
Only read it once; and check it for equality with FUBAR in a null-safe way:
return Objects.equals(bar.getFoo(), FUBAR);
// or
return FUBAR.equals(bar.getFoo());
Beside the obvious where bar may be null, the double call to bar.getFoo() is problematic. If we assume that other threads are running, then bar may be changed between the two calls to bar.getFoo() and return two different strings.
A solution would be to call bar.getFoo() only once and save the returned String as a local variable.
public boolean myMethod(final MyObject bar) {
if (bar == null)
return false;
String foo = bar.getFoo();
if (foo != null) {
return foo.equals(FUBAR);
} else {
return false;
}
}
Note: Even in non-multithreaded environment, bar.getFoo() may return different values for every call.

How to check multiple objects for nullity?

Often, I can see a code constructs like following:
if(a == null || b == null || c == null){
//...
}
I wonder if there is any widely used library (Google, Apache, etc.) to check against nullity for multiple objects at once, e.g.:
if(anyIsNull(a, b, c)){
//...
}
or
if(allAreNulls(a, b, c)){
//...
}
UPDATE:
I perfectly know how to write it by myself
I know it can be the result of the poor program structure but it's not a case here
Let's make it more challenging and replace original example with something like this:
if(a != null && a.getFoo() != null && a.getFoo().getBar() != null){
//...
}
UPDATE 2:
I've created a pull request for Apache Commons Lang library to fix this gap:
Issue: https://issues.apache.org/jira/browse/LANG-781
PR: https://github.com/apache/commons-lang/pull/108
These will be incorporated in commons-lang, version 3.5:
anyNotNull (Object... values)
allNotNull (Object... values)
In Java 8, you could use Stream.allMatch to check whether all of the values match a certain condition, such as being null. Not much shorter, but maybe a bit easier to read.
if (Stream.of(a, b, c).allMatch(x -> x == null)) {
...
}
And analogeously for anyMatch and noneMatch.
About your "more challenging example": In this case, I think there is no way around writing a lazy-evaluated conjunction of null-checks, like the one you have:
if (a != null && a.getFoo() != null && a.getFoo().getBar() != null) {
...
}
Any of the other approaches, using streams, lists, or var-arg methods, would try to evaluate a.getFoo() before a has been tested not to be null. You could use Optional with map and method pointers, that will be lazily evaluated one after the other, but whether this makes it any more readable is debatable and may vary from case to case (particularly for longer class names):
if (Optional.ofNullable(a).map(A::getFoo).map(B::getBar).isPresent()) {
...
}
Bar bar = Optional.ofNullable(a).map(A::getFoo).map(B::getBar).orElse(null);
Another alternative might be to try to access the innermost item, but I have a feeling that this is not considered good practice, either:
try {
Bar bar = a.getFoo().getBar();
...
catch (NullPointerException e) {
...
}
Particularly, this will also catch any other NPEs after accessing that element -- either that, or you have to put only the Bar bar = ... in the try and everything else in another if block after the try, nullifying any (questionable) gains in readability or brevity.
Some languages have a Safe Navigation Operator, but it seems like Java is not one of them. This way, you could use a notation like a?.getFoo()?.getBar() != null, where a?.getFoo() will just evaluate to null if a is null. You could emulate behavior like this with a custom function and a lambda, though, returning an Optional or just a value or null if you prefer:
public static <T> Optional<T> tryGet(Supplier<T> f) {
try {
return Optional.of(f.get());
} catch (NullPointerException e) {
return Optional.empty();
}
}
Optional<Bar> bar = tryGet(() -> a.getFoo().getBar(););
EDIT 2018: As of Apache Commons lang 3.5, there has been ObjectUtils.allNotNull() and ObjectUtils.anyNotNull().
No.
None of Apache Commons Lang (3.4), Google Guava (18) and Spring (4.1.7) provide such a utility method.
You'll need to write it on your own if you really, really need it. In modern Java code, I'd probably consider need for such a construct a code smell, though.
You could also use something like the following method. It allows you to pass as many parameters as you want:
public static boolean isAnyObjectNull(Object... objects) {
for (Object o: objects) {
if (o == null) {
return true;
}
}
return false;
}
You call it with as many parameters as you like:
isAnyObjectNull(a, b, c, d, e, f);
You could do something similar for areAllNull.
public static boolean areAllObjectsNull(Object... objects) {
for (Object o: objects) {
if (o != null) {
return false;
}
}
return true;
}
Note: you could also use the ternary operator instead of if (o == null). The two methods shown here have no error handling. Adjust it to your needs.
Objects.requireNonNull
It is possible with help of Objects class and its requireNonNull method.
public static void requireNonNull(Object... objects) {
for (Object object : objects) {
Objects.requireNonNull(object);
}
}
Apache commons-lang3 since version 3.11 has method ObjectUtils.allNull(Object... values)
ObjectUtils.allNull(obj1, obj2, obj3);
I was looking for a solution, but I don't have apache as a dependency yet and it felt silly to me to add it just for the allNonNull method. Here is my plain vanilla java solution using Predicate#and() / Predicate#or() like this:
private static boolean allNonNull(A a) {
Predicate<A> isNotNull = Objects::nonNull;
Predicate<A> hasFoo = someA -> someA.foo != null;
Predicate<A> hasBar = someA -> someA.foo.bar != null;
return Optional.ofNullable(a)
.filter(isNotNull.and(hasFoo.and(hasBar)))
.isPresent();
}
Note: for the anyNonNull, simply use the or() method instead of and().
When invoked, would give the following output:
System.out.println(isValid(new A(new Foo(new Bar())))); // true
System.out.println(isValid(new A(new Foo(null)))); // false
System.out.println(isValid(new A(null))); // false
System.out.println(isValid(null)); // false
Class definitions used:
public static class A {
public A(Foo foo) {
this.foo = foo;
}
Foo foo;
}
public static class Foo {
public Foo(Bar bar) {
this.bar = bar;
}
Bar bar;
}
public static class Bar { }
Simply as that:
Stream.of(a,b,c).allMatch(Objects::nonNull)
You can create a list of you objects and use yourList.contains(null) in it.
List < Object > obList = new ArrayList < Object > ();
String a = null;
Integer b = 2;
Character c = '9';
obList.add(a);
obList.add(b);
obList.add(c);
System.out.println("List is " + obList);
if (obList.contains(null)) {
System.out.println("contains null");
} else {
System.out.println("does not contains null");
}
DEMO

Evaluating multiple variable together in if condition

I was wondering whether its possible in java to evaluate multiple variables together in if-else condition like in python.
actual code
if(abc!=null && xyz!=null)
{//...}
dummy code
if(abc && xyz !=null)
{// will it be possible}
FIRST DRAFT
You can write smth like this:
boolean notNull(Object item) {
return item != null;
}
then you could use it like:
if (notNull(abc) && notNull(xyz)) {
//...
}
UPDATE 1:
I came up with a new idea, write function using varargs like:
boolean notNull(Object... args) {
for (Object arg : args) {
if (arg == null) {
return false;
}
}
return true;
}
usage: (you can pass to function multiple arguments)
if (notNull(abc, xyz)) {
//...
}
UPDATE 2:
The best approach is to use library apache commons ObjectUtils,
it contains several ready to use methods like:
allNotNull(Object... values),
anyNotNull(Object... values)
or firstNonNull(T... values)
the only way this would work is if abc was a boolean (and it wouldn't do what you're hoping it would do, it would simply test if abc == true). There is no way to compare one thing to multiple things in Java.
It's Impossible in java, you can use Varargs:
public boolean checkAnything(Object args...){
for(Object obj args){
if(...)
}
return ....;
}
See also:
Varargs
String… parameter in Java
Its not possible to that in Java. Instead you can do something like this:-
public boolean checkForNulls(Object... args){
List<Object> test = new ArrayList<Object>(Arrays.asList(args));
return test.contains(null); // Check if even 1 of the objects was null.
}
If any of the items is null, then the method will return true, else it'll return false. You can use it as per your requirements.
IMHO First is the better way and possible way.
Coming to second way ..if they are boolean values
if(abc && xyz )
{//...}

Assign if not null or if not set in Java

I am really tired of doing all the if null checks, resp. I also want to have a more configurable scenario for this. Let me explain this by an example:
I have a getter() which may return null or '0' in both cases the resp. setter() should not be called passing the getter().
So the implementation is
if(getter() != null && !getter().equals('0')) setter(getter());
this however really anoys me, especially if getter() and setter() are really long method calls and I have to introduce helper variables for this.
I am thinking about a method with parameter
ifNotSet(getter(), setter(), new Object[null, '0']);
which does exactly the same thing. Where the parameters to ifNotSet are
getter - the method to check if it does not equal one of the conditions
setter - the method to call in the way setter(getter) if conditions does not apply
conditions - the conditions which must not apply on evaluation of getter() for the method to be executed
At first sight this does not seem to complicated, it however is! Is anyone aware of a solution to this problem or any kind of implementation?
Thanks!
Update
I've been working some more on the problem, after the feedback of you guys, and found out about the following
private boolean ns(Object[] condition, Object getter) {
boolean ret = false;
for (Object object : condition) {
if(getter) equals or == ??
}
return true;
}
Object[] cond = new Object[] { null, "0" };
Object a;
if (ns(cond, a = getter()))setter(a);
Well, this seemed to be at least a solution if you have a lot of allocations to do. However, if you take a look at the ns() method... the question on the incoming conditions is, whether to use == or equals to do the comparison!?
You can use this way
public boolean checkNotNullOrZero(String s)
{
return (s!=null) && !s.equals("0");
}
Basic use:
if(checkNotNullOrZero(getter()))
{
setter(getter());
}
You can't do what that as in Java methods are not first-class citizens. You could use reflection or anon classes but it would be way more work .
If null and zero are always equivalent for getter then could that be changed to return just one of the two?
If null and zero are always equivalent for setter then could that be changed to normalize the two?
Could you create a method isNullOrZero(x) then you can have
if (!isNullOrZero(getter())) {
setter(getter());
}
Ugly way of doing this literally in Java:
public interface Getter {
public Object get();
}
public interface Caller {
public void call();
}
public void callIfNotNull(Getter getter, Caller caller, Object[] nullObjects) {
Object value = getter.get();
for(Object nullObject : nullObjects) {
if(value==nullObject) {
return;
}
}
caller.call();
}
Usage:
callIfNotNull(new Getter() {
#Override
public Object get() {
return getterMethod();
}
}, new Caller() {
#Override
public void call() {
setter();
}
}, new Object[]{null, '0'});
}
You might need to implement sane way to check for null objects and give reasonable names.
Personnaly, I wouldn't go with this approach. I would try to implement Null Object pattern to resolve an issue.

Hibernate criterion that matches against everything in some cases

is it possible to do something like
criteria.add(Expression.eq("product", " * "))
for it to match everything ?
It would be handy in case that you get a variable that can have many values and a special value "all" that matches against everything. So you can call a method like this and if the variable had a value of "all", then the expression would match everything.
public void someFunction(String variable) {
criteria.add(Expression.eq("product", variable))
}
EDITED: If I had 2 select fields with Source Language & Destination Language and a table listing entries based on which language combination it contains, with IF STATEMENTS it would look like this: (DynamicQuery is an abstraction for Criteria)
private DynamicQuery addCriteria(DynamicQuery dq, String languageFrom, String languageTo){
if (null != languageFrom && !languageFrom.isEmpty() && null != languageTo && !languageTo.isEmpty()){
if(languageFrom.equals("All") && languageTo.equals("All")) {
return dq;
} else if (!languageFrom.equals("All") && !languageTo.equals("All")) {
dq.add(PropertyFactoryUtil.forName("languageFrom").eq(languageFrom));
dq.add(PropertyFactoryUtil.forName("languageTo").eq(languageTo));
return dq;
} else if (languageFrom.equals("All") && !languageTo.equals("All")) {
dq.add(PropertyFactoryUtil.forName("languageTo").eq(languageTo));
return dq;
} else if (!languageFrom.equals("All") && languageTo.equals("All")) {
dq.add(PropertyFactoryUtil.forName("languageFrom").eq(languageFrom));
return dq;
}
}
}
It's disgusting, consider there would be one more field, it would be even more disgusting...One simply must cover all the combinations that might occur ... That's why I would like to have something like REGEX, because I would assign variable the reqex "*" value and I would add two lines like this
dq.add(PropertyFactoryUtil.forName("languageFrom").eq(languageFromVariable));
dq.add(PropertyFactoryUtil.forName("languageTo").eq(languageToVariable));
if (null != variable && !variable.isEmpty()){
criteria.add(Expression.eq("product", variable)) ;
}
If you only need it when it is selected. You may wanna add an if statement so criteria is added only when needed.
Edit 1:
You can define a method if you are gonna use it for more than fields. Even you can define different criterias inside here. Easy maintance (as is used by all and centrilized), code reuse (change at one point at it will be effective to all)
addCriteria(Criteria criteria, String name, String value){
//you wanna handle special cases like null == name as well accordingly
if (null != value && !value.isEmpty() && null != name && !name.isEmpty()){
criteria.add(Expression.eq(name, value)) ;
}
}

Categories

Resources