Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy13 cannot be cast to CustomeClass - spring-aop

I am trying to learn AOP with Spring Framework, but there is one exception that keeps on getting invoked.
Error : Exception in thread "main" java.lang.ClassCastException:
com.sun.proxy.$Proxy13 cannot be cast to com.controller.Triangle
Shape.java
package com.controller;
public interface Shape {
public void draw();
}
Triangle.java
package com.controller;
import org.springframework.stereotype.Component;
#Component
public class Triangle implements Shape
{
public void draw()
{
System.out.println("this draw method of triangle"),
}
}
myCustomAspect.java
package com.AOP;
import org.aspectj.lang.annotation.After;
#EnableAspectJAutoProxy
#Component
#Aspect
public class myCustomAspect {
#Pointcut("execution(* *.draw())")
private void pop(){}
#Before("pop()")
private void beforeMeth(){
System.out.println("this is before draw"); }
}
inside main method
ApplicationContext ssp = new ClassPathXmlApplicationContext("/Spring.xml");
Shape tr=(Triangle)ssp.getBean("triangle");
tr.draw();
Spring.XML
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop = "http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<context:annotation-config></context:annotation-config>
<context:component-scan base-package="com.controller,com.AOP"></context:component-scan>
</beans>
Please any one help.

Thanks for the MCVE, now it was easy to recreate your problem and verify the fix. Just reading the code and not being able to run it did not make me spot the problem.
It is very simple: Your advice beforeMeth() must be public. Then everything works like a charm.
Update:
Okay, I think I know what is missing on your part. You are casting the created bean to Triangle, but that is not an interface but a class, thus it cannot be proxied by Spring AOP without further configuration. So you have two options here:
Either you just change the code to Shape tr = (Shape) appContext.getBean("triangle"); so as to cast to the interface that is automatically used by Spring in order to create the JDK dynamic proxy.
Or you enable class proxying with CBLIB via <aop:aspectj-autoproxy proxy-target-class="true"/>. You can also use #EnableAspectJAutoProxy(proxyTargetClass = true) instead, of course.
Now here is a solution showing both approaches in parallel. You can switch by changing the value of XML_CONFIG.
BTW, I also corrected your package name com.AOP to com.aop (lower-case characters are the default for packages) and your Aspect name from myCustomAspect to MyCustomAspect (Java classes should start with an upper-case character). I also renamed Spring.xml to spring.xml. And in interfaces you do not need public for method declarations because all interface methods are by definition public. But all of this is just cosmetics, the real fix is the one above.
So here is your improved code:
package com.controller;
public interface Shape {
void draw();
}
package com.controller;
import org.springframework.stereotype.Component;
#Component
public class Triangle implements Shape {
public void draw() {
System.out.println("this draw method of triangle");
}
}
package com.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
#Component
#Aspect
public class MyCustomAspect {
#Pointcut("execution(* *.draw())")
private void pop() {}
#Before("pop()")
public void beforeMeth() {
System.out.println("this is before draw");
}
}
package de.scrum_master.app;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.controller.Shape;
import com.controller.Triangle;
#Configuration
#EnableAspectJAutoProxy(proxyTargetClass = true)
#ComponentScan(basePackages = { "com.controller", "com.aop" })
public class Application {
private static final boolean XML_CONFIG = true;
public static void main(String[] args) {
ApplicationContext appContext = XML_CONFIG
? new ClassPathXmlApplicationContext("/spring.xml")
: new AnnotationConfigApplicationContext(Application.class);
Shape tr = (Triangle) appContext.getBean("triangle");
tr.draw();
}
}
<?xml version = "1.0" encoding = "UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
">
<context:component-scan base-package="com.controller,com.aop"></context:component-scan>
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>

Related

replacement for camel cxfbean

we are currently struggling with updating our legacy service (non spring, jee + deltaspike, weld) and it's dependencies.
We try to upgrade from camel 2.16.2 to 3.x (due to java 11 compatibility).
We have already read through the migration guide several times, but could not find any reference to your replacement of the cxfbean component.
e.g.:
public class MonitoringRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
from("servlet:///monitoring?matchOnUriPrefix=true")
.to("cxfbean:monitoringService")
.setId("MonitoringRoute");
}
}
#Named("monitoringService")
public class MonitoringService implements MonitoringAPI {
#Override
public String status() {
return "OK";
}
}
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
public interface MonitoringAPI {
#GET
#Path("status")
#Produces(MediaType.TEXT_PLAIN)
String status();
}
We already tried cxfrs:monitoringService, but this will led to "Uri is not absolute" exception.
Any idea to replace cxfbean properly?

How to pass parameters to Apache Camel through command line?

I use Apache Camel’s Spring Main to boot my Camel application. I need my application to read the command line arguments to set some parameters. So, I cannot use property files.
At the moment, I can pass arguments via the JVM system properties, and it works well:
Application.java
public class Application extends org.apache.camel.spring.Main {
public static void main(String[] args) throws Exception {
Application app = new Application();
instance = app;
app.run(args);
}
}
camel-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="shutdownBean" class="com.example.ShutdownBean" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="file:{{inputFile}}?noop=true"/>
<to uri="bean:shutdownBean" />
</route>
</camelContext>
</beans>
I run the app with java com.example.Application -DinputFile=C:/absolute/path/to/watch and everything works fine:
…
FileEndpoint INFO Using default memory based idempotent repository with cache max size: 1000
InternalRouteStartupManager INFO Route: route1 started and consuming from: file://C:/absolute/path/to/watch
AbstractCamelContext INFO Total 1 routes, of which 1 are started
…
But I would like to have some input validation and make the app easier to use because -D could be confusing for a non Java user. So I change Application.java:
public class Application extends org.apache.camel.spring.Main {
private File inputFile;
public static void main(String[] args) throws Exception {
Application app = new Application();
instance = app;
app.run(args);
}
public Application() {
addOption(new ParameterOption("i", "inputFile", "The input file", "inputFile") {
#Override
protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
File file = FileUtils.getFile(parameter);
// some business validation
setInputFile(file);
}
});
}
private void setInputFile(File inputFile) {
this.inputFile = inputFile;
}
}
Then, I could use the following command to run the application: java com.example.Application -inputFile C:/absolute/path/to/watch
How can I use my inputFile field into my Camel route?
Call addProperty(String key, String value) in your doProcess method. Then it will be accessible throught {{key}} notation.
MyApplication:
public final class MyApplication extends Main {
private MyApplication() {
super();
addCliOption("g", "greeting", "Greeting");
addCliOption("n", "name", "Who to greet");
}
public static void main(String[] args) throws Exception {
MyApplication app = new MyApplication();
app.configure().addRoutesBuilder(MyRouteBuilder.class);
app.run(args);
}
private void addCliOption(String abbrevation, String parameterName, String description) {
addOption(new ParameterOption(abbrevation, parameterName, description, parameterName) {
protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
addProperty("console." + parameterName, parameter);
}
});
}
}
MyRouteBuilder:
public class MyRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
from("quartz:foo")
.log("{{console.greeting}} {{console.name}}");
}
}
java org.apache.camel.example.MyApplication -greeting Hello -name Morgan
23:10:25.862 [DefaultQuartzScheduler-MyCoolCamel_Worker-1] INFO route1 - Hello Morgan
23:10:26.832 [DefaultQuartzScheduler-MyCoolCamel_Worker-2] INFO route1 - Hello Morgan
23:10:27.829 [DefaultQuartzScheduler-MyCoolCamel_Worker-3] INFO route1 - Hello Morgan

Method created in 2nd class skipped while running 2 classes in Testng using xml

I had created 2 classes having 3 methods/test in these 2 classes. 2 methods/test in 1st class and 3rd method/test is in 2nd class. But when I run these using xml 1st class runs both the tests and tests pass where as method/test in 2nd class skips.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<suite name= "Expedia Call Tracker">
<test name="Expedia Home Smoke Testcases">
<classes>
<class name="ExpediaCallTracker.Expedia"/>
<class name="ExpediaCallTracker.ExpediaCreateSale" />
</classes>
</test>
</suite>
First Class :
package ExpediaCallTracker;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;
import org.testng.annotations.Test;
public class Expedia {
public String e;
WebDriver expedia = new FirefoxDriver();
#Test(priority=1)
public void ExpediaLogin()
{
expedia.manage().window().maximize();
expedia.get("http://fedev.teleperformanceusa.com/Expedia/ExpediaCallTracker/Account/Login");
expedia.findElement(By.id("UserName")).sendKeys("kochhar.5");
expedia.findElement(By.id("Password")).sendKeys("Password11");
expedia.findElement(By.xpath(".//*[#id='loginForm']/form/fieldset/p/input")).click();
}
#Test(priority=2)
public void ExpediaDashSale()
{
expedia.findElement(By.linkText("Sale - HWW/EAN")).click();
}
}
Second Class :
package ExpediaCallTracker;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class ExpediaCreateSale {
private static final WebDriver d = null;
public ExpediaCreateSale()
{
}
WebDriver expedia = d;
#Test
public void ExpediaCreate(WebDriver d)
{
expedia.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Select LineOfBusiness = new Select(expedia.findElement(By.id("lineOfBusiness")));
LineOfBusiness.selectByIndex(1);
expedia.findElement(By.id("sourceCode")).sendKeys("abcdefgh");
WebElement Upsell = expedia.findElement(By.xpath("html/body/div[1]/section[2]/form/fieldset/div[6]/input[1]"));
Upsell.click();
WebElement SaleCall =expedia.findElement(By.xpath("html/body/div[1]/section[2]/form/fieldset/div[8]/input[1]"));
SaleCall.click();
expedia.findElement(By.id("checkInDate")).sendKeys("09/14/2016");
Select numberOfNights = new Select(expedia.findElement(By.id("numberOfNights")));
numberOfNights.selectByIndex(1);
WebElement PaymentMethod = expedia.findElement(By.xpath("html/body/div[1]/section[2]/form/fieldset/div[9]/div[6]/input[1]"));
PaymentMethod.click();
Select currency = new Select(expedia.findElement(By.id("currency")));
currency.selectByIndex(70);
expedia.findElement(By.id("grossBooking")).sendKeys("123456");
expedia.findElement(By.id("itineraryNumber")).sendKeys("123456789");
expedia.findElement(By.id("remark")).sendKeys("Itinery number saved.");
expedia.findElement(By.xpath(".//*[#id='body']/section[2] /form/fieldset/p/input[1]")).click();
}
}
Can anyone suggest what should I try to do ?
Test method ExpediaCreate that takes a parameter WebDriver is causing this issue. To fix this, follow the same approach as Expedia class and it should work.
Moreover, you have not initialized webdriver instance variable d in the ExpediaCreateSale class. Once you initialize the driver instance, it is available in your test methods so you dont have to pass as a paramater.
You dont have to have this line of code also.
private static final WebDriver d = null;
Hope this helps.

Ejb3 -Accessing Local Enterprise Beans Using the No-Interface View

I'm trying to learn EJB3,
I created an EJB project with just a bean class:
package com;
import javax.ejb.Local;
import javax.ejb.Stateless;
#Stateless
#LocalBean
public class MyBean {
public MyBean() {
// TODO Auto-generated constructor stub
}
public String getMessage(){
return "Hello";
};
}
I deployed this project on Jboss 6 , then i create a Java project (adding in the build path the ejbProject above and Jboss-client.jar to make RMI calls).
for testing , this is the class i created:
import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.MyBean;
public class LanceProgram {
// #EJB
//public static MyBean mybean;
public static void main(String[] args) {
Context ctx;
try {
ctx = new InitialContext();
MyBean exampleBean = (MyBean) ctx.lookup("MyBean");
System.out.println(exampleBean.getMessage());
} catch (NamingException e) {
e.printStackTrace();
}
}
}
Normally, when running this, i should have a reference to MyBean,but it's null and i have this error message (using JNDI lookup):
Exception in thread "main" java.lang.ClassCastException: org.jnp.interfaces.NamingContext cannot be cast to com.MyBean
at LanceProgram.main(LanceProgram.java:17)
While with an EJB injection i have a NullPointerException !
this i my jndi.properties file specifications:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099
java.naming.factory.url.pkgs=org.jboss.ejb.client.naming
I'm trying to make a call to a bean which doesn't implements an interface.
Thanks for helping

Change EndPoint details in CXF ServiceInfo

The environment CXF2.2.6 and Spring 2.5. On Startup JBOSS I need to read CXF properties and change End point details. From basic reading it gives me the idea that CXF Service Info class (org.apache.cxf.service.model.ServiceInfo) handle bindings,endpoints,messages,schemas and so on.
I can Extend CXFServlet and create my own custom servlet. Please advise me the way I can give my own details to Endpoint in startup and override what is given in Spring.xml
The below Spring bean should do what you wanted. Why do you want to override ServiceInfo class ? Any particular reason ?
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.ServletContextAware;
public class CXFConfig implements InitializingBean{
#Autowired
Bus cxfBus;
#Override
public void afterPropertiesSet() throws Exception {
EndpointImpl endpoint = new EndpointImpl(cxfBus, new GdsAutomationServiceProviderImpl());
endpoint.setAddress("/public/api/service/v1");//WSDL URL
endpoint.setPublishedEndpointUrl(getEndPointAddress());
endpoint.publish();
}
public Bus getCxfBus() {
return cxfBus;
}
public void setCxfBus(Bus cxfBus) {
this.cxfBus = cxfBus;
}
public String getEndPointAddress() {
// Soap address location you need to define here
return "address"
}
#Override
public void setServletContext(ServletContext context) {
context.getServerInfo();
}
}

Resources