Spring AOP proxies does not work with JavaFX -


good day, i'm working on project use spring aop on javafx, unfortunately, when try wrap interface used in javafx scenes receive null pointer. here stack trace.

exception in application start method java.lang.reflect.invocationtargetexception     @ sun.reflect.nativemethodaccessorimpl.invoke0(native method)     @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62)     @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)     @ java.lang.reflect.method.invoke(method.java:483)     @ com.sun.javafx.application.launcherimpl.launchapplicationwithargs(launcherimpl.java:363)     @ com.sun.javafx.application.launcherimpl.launchapplication(launcherimpl.java:303)     @ sun.reflect.nativemethodaccessorimpl.invoke0(native method)     @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62)     @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)     @ java.lang.reflect.method.invoke(method.java:483)     @ sun.launcher.launcherhelper$fxhelper.main(launcherhelper.java:767) caused by: java.lang.runtimeexception: exception in application start method     @ com.sun.javafx.application.launcherimpl.launchapplication1(launcherimpl.java:875)     @ com.sun.javafx.application.launcherimpl.lambda$launchapplication$147(launcherimpl.java:157)     @ com.sun.javafx.application.launcherimpl$$lambda$48/756185697.run(unknown source)     @ java.lang.thread.run(thread.java:745) caused by: java.lang.nullpointerexception     @ javafx.scene.node.getscene(node.java:907)     @ javafx.scene.scene$9.invalidated(scene.java:1074)     @ javafx.beans.property.objectpropertybase.markinvalid(objectpropertybase.java:111)     @ javafx.beans.property.objectpropertybase.set(objectpropertybase.java:145)     @ javafx.scene.scene.setroot(scene.java:1038)     @ javafx.scene.scene.<init>(scene.java:325)     @ javafx.scene.scene.<init>(scene.java:181)     @ com.hccs.sample.aspectj.main.start(main.java:42)     @ com.sun.javafx.application.launcherimpl.lambda$launchapplication1$153(launcherimpl.java:821)     @ com.sun.javafx.application.launcherimpl$$lambda$51/50630420.run(unknown source)     @ com.sun.javafx.application.platformimpl.lambda$runandwait$166(platformimpl.java:323)     @ com.sun.javafx.application.platformimpl$$lambda$44/1051754451.run(unknown source)     @ com.sun.javafx.application.platformimpl.lambda$null$164(platformimpl.java:292)     @ com.sun.javafx.application.platformimpl$$lambda$47/1570685826.run(unknown source)     @ java.security.accesscontroller.doprivileged(native method)     @ com.sun.javafx.application.platformimpl.lambda$runlater$165(platformimpl.java:291)     @ com.sun.javafx.application.platformimpl$$lambda$46/1775282465.run(unknown source)     @ com.sun.glass.ui.invokelaterdispatcher$future.run(invokelaterdispatcher.java:95)     @ com.sun.glass.ui.win.winapplication._runloop(native method)     @ com.sun.glass.ui.win.winapplication.lambda$null$141(winapplication.java:102)     @ com.sun.glass.ui.win.winapplication$$lambda$37/1109371569.run(unknown source)     ... 1 more exception running application com.hccs.sample.aspectj.main 

here main method, create instance of myscene interface , wrap proxy.

public class main extends application {      private static applicationcontext context;      public static void main(string[] args) {         context = new annotationconfigapplicationcontext(appconfig.class);         application.launch(main.class);     }      @override     public void start(stage primarystage) throws exception {         myscene scene = context.getbean(myscene.class);         if (scene == null) {             system.out.println("scene null on creation");             system.exit(0);         } else {             system.out.println("scene not null on creation.");         }          // these code source of problem, when these code         // commented, works fine.         scene = proxywrapper.wrap(scene);         if (scene == null) {             system.out.println("scene null on wrapping");             system.exit(0);         } else {             system.out.println("scene not null on wrapping");         }         // comment here          // no problem manual invocation of methods         scene.eventone();         scene.eventtwo();         scene.eventthree();          // null pointer occurs         primarystage.setscene(new scene((parent) scene));         primarystage.show();     } } 

here application config.

@configuration @componentscan(basepackages = { "com.hccs.sample.aspectj" }) public class appconfig {  } 

here scene interface , implementation needs wrapped.

public interface myscene {     public void initialize();      public void eventone();      public void eventtwo();      public void eventthree();  }  @lazy @component public class mysceneimpl extends borderpane implements myscene {      @fxml     private button cmdone;     @fxml     private button cmdtwo;     @fxml     private button cmdthree;      public mysceneimpl() {         try {             fxmlloader loader = new fxmlloader(getclass().getresource(                     "/com/hccs/sample/aspectj/resources/myscene.fxml"));             loader.setroot(this);             loader.setcontroller(this);             loader.load();             system.out.println("\nkards!!\n");         } catch (exception e) {             e.printstacktrace();         }     }      @fxml     @override     public void initialize() {     }      @fxml     @override     public void eventone() {         system.out.println("one");     }      @fxml     @override     public void eventtwo() {         looptoten();     }      @override     public void eventthree() {         new thread() {             @override             public void run() {                 looptoten();             }         }.start();     }      private void looptoten() {         (int c = 0; c < 10; c++) {             try {                 thread.sleep(100);                 system.out.println(c + 1);             } catch (interruptedexception e) {                 e.printstacktrace();             }         }      }  } 

here fxml used in scene,

<fx:root type="borderpane" xmlns:fx="http://javafx.com/fxml/1"     xmlns="http://javafx.com/javafx/8">     <center>         <hbox alignment="center" spacing="10.0" borderpane.alignment="center">             <children>                 <button fx:id="cmdone" mnemonicparsing="false" onaction="#eventone"                     text="one" />                 <button fx:id="cmdtwo" mnemonicparsing="false" onaction="#eventtwo"                     text="two" />                 <button fx:id="cmdthree" mnemonicparsing="false" onaction="#eventthree"                     text="three" />             </children>         </hbox>     </center>     <padding>         <insets bottom="10.0" left="10.0" right="10.0" top="10.0" />     </padding> </fx:root> 

this class wraps scene.

public class proxywrapper {     @suppresswarnings("unchecked")     public static <t> t wrap(t scene) {         mypointcut pointcut = new mypointcut();         mymethodinterceptor aspect = new mymethodinterceptor();         advisor advisor = new defaultpointcutadvisor(pointcut, aspect);         proxyfactory pf = new proxyfactory();         pf.settarget(scene);         pf.addadvisor(advisor);         return (t) pf.getproxy();     } } 

this pointcut , methodinterceptor classes.

public class mypointcut extends dynamicmethodmatcherpointcut {      @override     public classfilter getclassfilter() {         return new classfilter() {             @override             public boolean matches(class<?> clazz) {                 return clazz.getname().contains("myscene");             }         };     }      @override     public boolean matches(method method, class<?> clazz, object[] key) {         system.out.println(method.getname() + " == event "                 + method.getname().contains("event"));         return method.getname().contains("eventt");     }  }  @aspect public class mymethodinterceptor implements methodinterceptor {     @override     public object invoke(methodinvocation invocation) throws throwable {         system.out.println("start: " + invocation.getmethod().getname());         object val = invocation.proceed();         system.out.println("end: " + invocation.getmethod().getname());         return val;     } } 

and pom.xml of project.

<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"     xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelversion>4.0.0</modelversion>     <groupid>com.hccs.sample</groupid>     <artifactid>sample-aspectj</artifactid>     <version>1.0.0</version>     <name>sample-aspectj</name>      <dependencies>         <dependency>             <groupid>org.springframework</groupid>             <artifactid>spring-core</artifactid>             <version>4.1.6.release</version>         </dependency>         <dependency>             <groupid>org.springframework</groupid>             <artifactid>spring-context</artifactid>             <version>4.1.6.release</version>         </dependency>         <dependency>             <groupid>org.springframework</groupid>             <artifactid>spring-aop</artifactid>             <version>4.1.6.release</version>         </dependency>         <dependency>             <groupid>org.aspectj</groupid>             <artifactid>aspectjrt</artifactid>             <version>1.8.5</version>         </dependency>         <dependency>             <groupid>org.aspectj</groupid>             <artifactid>aspectjweaver</artifactid>             <version>1.8.5</version>         </dependency>         <dependency>             <groupid>aopalliance</groupid>             <artifactid>aopalliance</artifactid>             <version>1.0</version>         </dependency>     </dependencies> </project> 

if there's way me make javafx recognize spring aop proxies, please share , me, thanks!

i can't quite figure out why fails, making mysceneimpl subclass of borderpane causing problem. basically, proxy that's created in order intercept methods not initialize borderpane instance correctly.

the fix use aggregation instead of inheritance. add method myscene:

public parent getview() ; 

and update implementation class accordingly:

@lazy @component public class mysceneimpl implements myscene {      @fxml     private button cmdone;     @fxml     private button cmdtwo;     @fxml     private button cmdthree;      private final borderpane view ;      public mysceneimpl() {          view = new borderpane();          try {             fxmlloader loader = new fxmlloader(getclass().getresource(                     "/application/myscene.fxml"));             loader.setroot(view);             loader.setcontroller(this);             loader.load();             system.out.println("\nkards!!\n");         } catch (exception e) {             e.printstacktrace();         }     }      @fxml     @override     public void initialize() {     }      @override     public parent getview() {         return view ;     }      @fxml     @override     public void eventone() {         system.out.println("one");     }      @fxml     @override     public void eventtwo() {         looptoten();     }      @override     public void eventthree() {         new thread() {             @override             public void run() {                 looptoten();             }         }.start();     }      private void looptoten() {         (int c = 0; c < 10; c++) {             try {                 thread.sleep(100);                 system.out.println(c + 1);             } catch (interruptedexception e) {                 e.printstacktrace();             }         }      }  } 

here, instead of making mysceneimpl subclass of borderpane, holds reference borderpane instance. reference passed fxmlloader's setroot() method, gets populated buttons defined in fxml. finally, returned getview() method.

now update main class call getview():

// primarystage.setscene(new scene((parent) scene)); primarystage.setscene(new scene(scene.getview())); 

Popular posts from this blog

c# - ODP.NET Oracle.ManagedDataAccess causes ORA-12537 network session end of file -

matlab - Compression and Decompression of ECG Signal using HUFFMAN ALGORITHM -

utf 8 - split utf-8 string into bytes in python -