AspectJ Before can return from method? - java

Can I return from method with annotation #Before in AspectJ.
#Before
public void simpleAdvice(JoinPoin joinPoint) {
if (smth == null)
/* return for method, which annotated */
}
If my question is not fully, please ask me another for details.

You can define a method using the #Before , #After , #AfterReturning , #AfterThrowing , #Around . But your class can be registered with the #Aspect .
Also you need to define the pointcut and joinpoints.
For example,
#Before(value="execution(* com.pointel.aop.AopTest.beforeAspect(..))")
public void beforeAdvicing(JoinPoint joinPoint){
String name = joinPoint.getSignature().getName();
System.out.println("Name of the method : "+name);
}
#AfterReturning(value="execution(* com.pointel.aop.AopTest.beforeAspect(..))")
public void beforeAdvicing(JoinPoint joinPoint,Object result){
String name = joinPoint.getSignature().getName();
System.out.println("Name of the method : "+name);
System.out.println("Method returned value is : " + result);
}
Your Java class will be,
package com.pointel.aop;
public class AopTest {
public String beforeAspect( ) {
return "I am a AopTest";
}
}
That's it.Hope it helps.

#Aspect
#SuppressAjWarnings({ "adviceDidNotMatch" })
public class TestAspect {
#Around("execution(#Monitor void *..*.* ())")
public void aroundMethodWithMonitorAnnotation(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.err.println("Around - before a()");
String sessionId = (String) proceedingJoinPoint.getArgs()[0];
if(sessionId != null){
proceedingJoinPoint.proceed();
System.err.println("Around - after a()");
} else {
System.err.println("Around - a() not called");
}
}
public static void main(String[] args) {
new TestAspect().a();
}
#Retention(RetentionPolicy.RUNTIME)
#Target({ ElementType.METHOD })
public #interface Monitor {
}
#Monitor
public void a() {
System.err.println("a()");
}
}

Related

Spring AOP pointcut expression excluding a particular return type or argument

#AfterReturning(value = "execution(* org.springframework.data.repository.CrudRepository.save(..)) ", returning = "result")
public void repo(JoinPoint joinPoint, Object result) {
// ...
}
This pointcut covers all save or update operations irrespective of the argument passed or return type but I want to exclude just xyz.class in arguments or return type. How is that possible?
I can not mention all save operations because there are total 50+ models but I want only 48 of them to be covered.
#Pointcut("execution(* com.yash.arci.repository.*.save(*))")
public void allrepository() {
}
#Pointcut("execution(* com.yash.arci.repository.AuditRepository.save(*))")
public void auditrepository() {
}
#Before(value = "allrepository() && !auditrepository()")
public void repo(JoinPoint joinPoint) {
}
This is the alternate solution.
You declare included and excluded method signatures and combine them like this
#Pointcut("execution(* org.springframework.data.repository.CrudRepository.save(..))")
public void any() {
}
#Pointcut("execution(* org.springframework.data.repository.CrudRepository.save(MyClass1))" +
" || execution(* org.springframework.data.repository.CrudRepository.save(MyClass2))")
public void excluded() {
}
#AfterReturning(value = "any() && !excluded()", returning = "result")
public void repo(JoinPoint joinPoint, Object result) {
// ...
}
The simplest thing you can do keeping in mind the erasure of a type, is just return from the method without doing anything, if the arg type is XYZ.
#Pointcut("execution(* org.springframework.data.repository.CrudRepository+.save(..))")
public void savePointCut() {
// savePointCut
}
#AfterReturning(value = "savePointCut()", returning = "result")
public void afterReturning(JoinPoint joinPoint, Object result) {
if (joinPoint.getArgs()[0] instanceof XYZ) return;
logger.info("AfterReturning :[{}]", joinPoint.getArgs());
}

How to invoke child class method from parent class through reflection

I want to create a menu which should be populated by arbitrary methods, which are marked by an annotation. The methods should be invoked from inside the base class. Unfortunately 'java.lang.ClassCastException' is thrown since the method.invoke function expects an object which is instance of the child class. But i only get the base class.
Here is what i tried so far :
public abstract Class BaseClass{
private void invokeSomeMethod(){
final Method[] methods= getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MenuFunction.class)) {
MenuFunction menuFunction = method.getAnnotation(MenuFunction.class);
menuFunction.invoke(this); //Throws 'java.lang.ClassCastException'
}
}
}
#Retention(RetentionPolicy.RUNTIME)
#Target({ METHOD })
public #interface MenuFunction {
String Label();
}
}
public Class ChildClass extends BaseClass{
#MenuFunction(Label = "First method")
public void setHigh(){
//Arbitrary function
}
#MenuFunction(Label = "Another method")
public void setLow(){
//Do something
}
}
I guess what you want to do is this:
public abstract class BaseClass {
public void invokeSomeMethod() throws InvocationTargetException, IllegalAccessException {
final Method[] methods = getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MenuFunction.class)) {
MenuFunction menuFunction = method.getAnnotation(MenuFunction.class);
method.invoke(this); //invoke method here'
}
}
}
}
public class ChildClass extends BaseClass{
#MenuFunction(Label = "hello")
public void hello() {
System.out.println("hello");
}
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
new ChildClass().invokeSomeMethod();
}
}
Result:
hello

How to find how many testcase are there in TestNG class from another java class

I have two class
public class xyzTest {
#Test
public void TestP1TUNG557(){
TestHelper.excuteTestcase(TUNG557);
Assert.assertTrue(TestHelper.TestResult);
}
#Test
public void TestP1TUNG559(){
TestHelper.excuteTestcase(TUNG559);
Assert.assertTrue(TestHelper.TestResult);
}
#Test
public void TestP0TUNG558(){
TestHelper.excuteTestcase(TUNG558);
Assert.assertTrue(TestHelper.TestResult);
}
}
public class TestHelper {
public excuteTestcase(String abc)
{
process(abc)
}
int TotalTescase(String pattern, Class testNGclass)
{
How to write here..? plz help
}
}
suppose if have called TotalTescase(String TestPO, Class xyzTest), it should return 1 and if have called TotalTescase(String TestP1, Class xyzTest) it should return 2.
If This is possible to get total test case like this ,plz help me or provide me some link
I have searched but i couldnt find. help me
You can use reflection technique to find out the matching methods in the supplied class like:
public int TotalTescase(String pattern, Class<?> testNGclass) throws ClassNotFoundException
{
int count = 0;
testNGclass.getClass();
Class<?> className = Class.forName(testNGclass.getName());
Method[] methods = className.getMethods();
for(int i=0; i<methods.length; i++)
{
String methodName = methods[i].getName();
System.out.println("Method Name: "+methodName);
if(methodName.contains(pattern))
{
count++;
}
}
return count;
}
In dry run try to implement IInvokedMethodListener and override beforeInvocation method
public class Test implements IInvokedMethodListener
{
static int testcount=0;
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
testcount=testcount+method.getTestMethod().getInvocationCount();
}
#Override
public void onStart(ISuite suite) {
// TODO Auto-generated method stub
}
#Override
public void onFinish(ISuite suite) {
System.out.println(testcount);
}
}

I wish to run test cases based on the run mode declared in an excel

Please find the below codes and the query mentioned at the last.
**Annotation List**
public interface AnnotationList{
#Documented
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
public #interface QCID {
String[] value();
}
#Documented
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
public #interface Author {
String value();
}
#Documented
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Order {
int value();
}
#Documented
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface MyTest {
static class None extends Throwable {
private static final long serialVersionUID = 1L;
private None() {
}}
JUnitLink
public class JunitLink extends BlockJUnit4ClassRunner {
// TODO work in test status to see if things should be run.
public static final Logger logger = LoggerFactory.getLogger(JunitLink.class);
public JunitLink(Class<?> klass) throws InitializationError {
super(klass);
}
#Override
public void run(final RunNotifier notifier) {
JunitLink.super.run(notifier);
}
#Override
protected List<FrameworkMethod> computeTestMethods() {
List<FrameworkMethod> classMethods = getTestClass().getAnnotatedMethods(AnnotationList.MyTest.class);
SortedMap<Integer, FrameworkMethod> sortedTestMethodList = new TreeMap<Integer,FrameworkMethod>();
for (FrameworkMethod seleniumTest : classMethods) {
if (seleniumTest.getAnnotation(AnnotationList.Order.class) != null) {
sortedTestMethodList.put(seleniumTest.getAnnotation(AnnotationList.Order.class).value(),seleniumTest);
}
}
return new ArrayList<FrameworkMethod>(sortedTestMethodList.values());
}
#Override
protected void runChild(FrameworkMethod method, RunNotifier notifier) {
EachTestNotifier eachNotifier = makeNotifier(method, notifier);
if (method.getAnnotation(Ignore.class) != null) {
runIgnored(eachNotifier);
} else {
runNotIgnored(method, eachNotifier);
}
logger.info("Test {} run completed", method.getName());
}
private int runNotIgnored(FrameworkMethod method,EachTestNotifier eachNotifier) {
int failures = 0;
eachNotifier.fireTestStarted();
try {
methodBlock(method).evaluate();
}
catch (AssumptionViolatedException e) {
eachNotifier.addFailedAssumption(e);
logger.error("Test {} failed!", method.getName());
failures++;
}
catch (Throwable e) {
eachNotifier.addFailure(e);
logger.error("Test {} failed!", method.getName());
failures++;
} finally {
eachNotifier.fireTestFinished();
}
return failures;
}
private void runIgnored(EachTestNotifier eachNotifier) {
eachNotifier.fireTestIgnored();
}
private EachTestNotifier makeNotifier(FrameworkMethod method,RunNotifier notifier) {
Description description = describeChild(method);
return new EachTestNotifier(notifier, description);
}}
Start Up Test
#RunWith(JunitLink.class)
public class StartUp extends SeleneseTestBase {
public static readProperties settings = new readProperties();
public static final Logger LOGGER = LoggerFactory.getLogger(INF.class);
public static WebDriver driver;
public static Actions actions;
#Override
#Before
public void setUp()
{
}
#Override
#After
public void tearDown() {
}
#BeforeClass
public static void StartBrowser() {
//Start Driver etc
}
#AfterClass
public static void tearClassDown() {
//Kill driver
}
}
//Test Cases Are Written Like These
#Author("XXXX")
#QCID({ "Smoke_TC01", "Smoke_TC02", "Smoke_TC03",
"TC04"})
public class SmokeTest extends Startup{
private Components component = new Components();
private String TestDataSheetName = "Smoke";
public SmokeTest() throws Exception {
}
#MyTest
#Order(1)
public void openHomepage() throws Exception {
component.openAPP();
}
#MyTest
#Order(2)
public void Login() throws Exception {
component.Login(USID, PWD);
}
#MyTest
#Order(3)
public void isTerminalLocked() throws Exception {
component.isTerminalLocked();
}
All the test method runs in order. Now I want to run only specific test cases which have runmode as "Yes" declared in a excel. I can add extraline before each test cases to read the lines from excel and run the particular test case but I want to read the excel and pass the selected testcases(based on runmode) to Junit runner.
Please help me.
I think your question is borderline "too broad". It's possible it may get closed for this reason.
Have a look at A JUnit Rule to Conditionally Ignore Tests. From that your isSatisfied() will have to parse your Excel. You can use something like Apache POI to do this.

How to resolve exception in thread main NoClassDefFoundError in Java?

For the first time I dealing with Java Annotations. So please pardon me if I m doing anything wrong ! But this class compiled successfully using javac MyFirstAnnotation.java
but when I try to run this source code using java TestMyAnnotation
it throws an error like this
package Annotations;
import java.lang.annotation.*;
import java.util.*;
import java.lang.reflect.*;
#Documented
#Target(ElementType.METHOD)
#Inherited
#Retention(RetentionPolicy.RUNTIME)
public #interface MyFirstAnnotation
{
String author() default "Chiranjib Nandy";
int revisionNumber() default 1;
String date();
}
class MySuperClass
{
public String showMe()
{
return "Do Something";
}
}
class MyAnnotation extends MySuperClass
{
#Override
#MyFirstAnnotation(author="Recmach",revisionNumber=2,date="1st June,2014")
public String showMe()
{
return "Display Something";
}
#Deprecated
#MyFirstAnnotation(revisionNumber=2,date="2nd June,2014")
public void oldMethod()
{
System.out.println("It is a deprecated method");
}
#SuppressWarnings({"unused","deprecation"})
#MyFirstAnnotation(author="Papai",date="1st June,2014")
public void myMethod()
{
int j;
oldMethod();
System.out.println("It is defined in my way");
}
}
class TestMyAnnotation
{
public static void main(String[] args) throws ClassNotFoundException
{
Method myMethods[]=Class.forName("Annotations.MyAnnotation").getDeclaredMethods();
for(Method m : myMethods)
{
Annotation[] annotations=m.getDeclaredAnnotations();
for(Annotation anno : annotations)
{
if(anno instanceof MyFirstAnnotation)
{
MyFirstAnnotation myFirstAnnotation = (MyFirstAnnotation) anno;
System.out.println("name : "+myFirstAnnotation.author());
System.out.println("name : "+myFirstAnnotation.revisionNumber());
System.out.println("name : "+myFirstAnnotation.date());
}
}
}
}
}
Three issues that I fixed.
The public class needs to be TestMyAnnotation.
This line should be MyAnnotation, not what it was before
Method myMethods[]=Class.forName("MyAnnotation").getDeclaredMethods();
The first class at the top should not be public, because you cannot have two public classes inside one file.
Take the following code and put it inside TestMyAnnotation.java. Then run javac TestMyAnnotation.java, followed by java TestMyAnnotation.
import java.lang.annotation.*;
import java.util.*;
import java.lang.reflect.*;
#Documented
#Target(ElementType.METHOD)
#Inherited
#Retention(RetentionPolicy.RUNTIME)
#interface MyFirstAnnotation
{
String author() default "Chiranjib Nandy";
int revisionNumber() default 1;
String date();
}
class MySuperClass
{
public String showMe()
{
return "Do Something";
}
}
class MyAnnotation extends MySuperClass
{
#Override
#MyFirstAnnotation(author="Recmach",revisionNumber=2,date="1st June,2014")
public String showMe()
{
return "Display Something";
}
#Deprecated
#MyFirstAnnotation(revisionNumber=2,date="2nd June,2014")
public void oldMethod()
{
System.out.println("It is a deprecated method");
}
#SuppressWarnings({"unused","deprecation"})
#MyFirstAnnotation(author="Papai",date="1st June,2014")
public void myMethod()
{
int j;
oldMethod();
System.out.println("It is defined in my way");
}
}
public class TestMyAnnotation
{
public static void main(String[] args) throws ClassNotFoundException
{
Method myMethods[]=Class.forName("MyAnnotation").getDeclaredMethods();
for(Method m : myMethods)
{
Annotation[] annotations=m.getDeclaredAnnotations();
for(Annotation anno : annotations)
{
if(anno instanceof MyFirstAnnotation)
{
MyFirstAnnotation myFirstAnnotation = (MyFirstAnnotation) anno;
System.out.println("name : "+myFirstAnnotation.author());
System.out.println("name : "+myFirstAnnotation.revisionNumber());
System.out.println("name : "+myFirstAnnotation.date());
}
}
}
}
}
Hope this link helps.
http://www.shivasoft.in/blog/java/compile-and-run-java-program-in-package-from-command-line/
This is already in stack overflow. You have to compile your class with package like in this post.
try run your Main Java class with adding -cp (classpath) like below commands:
java -cp . TestMyAnnotation
Hope it helps.

Categories

Resources