1

I've tried to add logging via Spring Aspects to my project, but the aspects never run.

This is the file where I define the aspects: LoggingInfo.java

package org.synyx.sybil.config; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Aspect public class LoggingInfo { private static final Logger LOG = LoggerFactory.getLogger(LoggingInfo.class); @Pointcut("execution(* com.tinkerforge.IPConnection.connect(String, int)) && args(host, port)") public void connect(String host, int port) { } @Before("connect(host, port)") public void CreateIPConnection(String host, int port) { LOG.info("Creating IPConnection to {}:{}", host, port); }`enter code here` @AfterReturning("connect(host, port)") public void FinishedCreatingIPConnection(String host, int port) { LOG.info("Successfully created IPConnection to {}:{}", host, port); } @AfterThrowing("connect(host, port)") public void FailedCreatingIPConnection(String host, int port) { LOG.info("Failed creating IPConnection to {}:{}", host, port); } } 

This is my Spring config: SpringConfigDev.java

package org.synyx.sybil.config; import com.tinkerforge.AlreadyConnectedException; import com.tinkerforge.BrickletLEDStrip; import com.tinkerforge.IPConnection; import com.tinkerforge.NotConnectedException; import com.tinkerforge.TimeoutException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.Scope; import org.springframework.core.env.Environment; import org.synyx.sybil.out.OutputLEDStrip; import org.synyx.sybil.out.SingleStatusOnLEDStrip; import org.synyx.sybil.out.SingleStatusOutput; import java.io.IOException; @Profile("dev") @Configuration @EnableAspectJAutoProxy @PropertySource("classpath:SpringConfigDev.properties") public class SpringConfigDev { // private static final Logger LOG = LoggerFactory.getLogger(SpringConfigDev.class); @Autowired Environment env; @Bean(destroyMethod = "disconnect") @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public IPConnection ipConnection() throws AlreadyConnectedException, IOException { String hostname = env.getRequiredProperty("ipconnection.hostname"); int port = env.getProperty("ipconnection.port", Integer.class, 4223); // 4223 is the standard port // LOG.info("Creating IPConnection to {}:{}", hostname, port); IPConnection ipConnection = new IPConnection(); ipConnection.connect(hostname, port); // LOG.info("Successfully connected to {}:{}", hostname, port); return ipConnection; } @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public BrickletLEDStrip brickletLEDStrip(IPConnection ipConnection) throws TimeoutException, NotConnectedException { BrickletLEDStrip brickletLEDStrip = new BrickletLEDStrip(env.getRequiredProperty("brickletledstrip.uid"), ipConnection); brickletLEDStrip.setFrameDuration(10); brickletLEDStrip.setChipType(2812); return brickletLEDStrip; } @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public OutputLEDStrip outputLEDStrip(BrickletLEDStrip brickletLEDStrip) { return new OutputLEDStrip(brickletLEDStrip, env.getRequiredProperty("outputledstrip.length", Integer.class)); } @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public SingleStatusOutput singleStatusOutput(OutputLEDStrip outputLEDStrip) { return new SingleStatusOnLEDStrip(outputLEDStrip); } } 

Everything in here works, execpt - apparently - for the @EnableAspectJAutoProxy.

This is the test I'm using to run it: OutputLEDStripTest.java

package org.synyx.sybil.out; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.synyx.sybil.config.SpringConfigDev; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { SpringConfigDev.class }) public class OutputLEDStripTest { @Autowired private OutputLEDStrip outputLEDStrip; @After public void close() { // throws NotConnectedException { outputLEDStrip.setBrightness(1.0); outputLEDStrip.setColor(Color.BLACK); outputLEDStrip.updateDisplay(); } @Test public void testSetColor() throws Exception { outputLEDStrip.setColor(new Color(16, 32, 8)); outputLEDStrip.updateDisplay(); Color pixel = outputLEDStrip.getPixel(0); assertEquals("Pixel 0.red should be 16", 16, pixel.getRed()); assertEquals("Pixel 0.green should be 32", 32, pixel.getGreen()); assertEquals("Pixel 0.blue should be 8", 8, pixel.getBlue()); } @Test public void testSetPixel() throws Exception { Color color = new Color(16, 35, 77); outputLEDStrip.setPixel(1, color); outputLEDStrip.updateDisplay(); Color pixel0 = outputLEDStrip.getPixel(0); Color pixel1 = outputLEDStrip.getPixel(1); assertEquals("Pixel 0.red should be 0", 0, pixel0.getRed()); assertEquals("Pixel 0.green should be 0", 0, pixel0.getGreen()); assertEquals("Pixel 0.blue should be 0", 0, pixel0.getBlue()); assertEquals("Pixel 1.red should be 16", 16, pixel1.getRed()); assertEquals("Pixel 1.green should be 35", 35, pixel1.getGreen()); assertEquals("Pixel 1.blue should be 77", 77, pixel1.getBlue()); } @Test public void testSetBrightnessHalf() throws Exception { outputLEDStrip.setColor(Color.WHITE); outputLEDStrip.setBrightness(.5); outputLEDStrip.updateDisplay(); Color pixel = outputLEDStrip.getPixel(0); assertTrue("Pixel 0 should be half as bright as a full white (127, 127, 127).", pixel.getRed() == (short) (127 * .5) && pixel.getGreen() == (short) (127 * .5) && pixel.getBlue() == (short) (127 * .5)); } @Test public void testSetBrightnessFull() throws Exception { outputLEDStrip.setColor(Color.WHITE); outputLEDStrip.setBrightness(1); outputLEDStrip.updateDisplay(); Color pixel = outputLEDStrip.getPixel(0); assertTrue("Pixel 0 should be full white (127, 127, 127).", pixel.getRed() == 127 && pixel.getGreen() == 127 && pixel.getBlue() == 127); } @Test public void testSetBrightnessDouble() throws Exception { outputLEDStrip.setColor(Color.WHITE); outputLEDStrip.setBrightness(2); outputLEDStrip.updateDisplay(); Color pixel = outputLEDStrip.getPixel(0); assertTrue("Pixel 0 should be double as bright as a full white (127, 127, 127).", pixel.getRed() == (short) (127 * 2) && pixel.getGreen() == (short) (127 * 2) && pixel.getBlue() == (short) (127 * 2)); } } 

You won't be able to sucessfully run this project unless you install the Tinkerforge brickd damon and have a Tinkerforge brick with a LED Strip bricklet connected somewhere and the SpringConfigDev.properties file set up for it. But, if logging worked, you should see the error messages in the log file.

8
  • Your aspect isn't added as a bean so the aspectj support doesn't know about the aspect and it will be happily ignored. Commented Dec 22, 2014 at 14:31
  • How would I go about that? Just adding @Bean public LoggingInfo loggingInfo() { LoggingInfo loggingInfo = new LoggingInfo(); return loggingInfo; } Does not seem to help Commented Dec 22, 2014 at 14:39
  • 1
    The ipConnection.connect(hostname, port) in the ipConnection() will not trigger the aspect as the ipConnect is instantiated per new. Commented Dec 22, 2014 at 14:39
  • 1
    Further you need to call the connect outside the place where you call the new. Commented Dec 22, 2014 at 14:41
  • 1
    @TobiasTheuer As M.Deinum answered, your aspects needs to be also Spring beans. Just annotate them via Component annotation Commented Dec 22, 2014 at 14:42

1 Answer 1

1

Spring configuration hints are all okay, but I guess they will not help because the pointcut says:

execution(* com.tinkerforge.IPConnection.connect(String, int)) 

The thing is: I assume that the Tinkerforge classes are not Spring components, i.e. they cannot be targeted by Spring AOP execution() pointcuts. So either you switch to full AspectJ and use a call() pointcut (unavailable in Spring AOP) or as a workaround you change your pointcut to target one of your Spring components' methods which has the same information. ;-)

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.