--- /dev/null
+package foo;
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface Synchronized {}
--- /dev/null
+package foo;
+
+import org.aspectj.lang.annotation.SuppressAjWarnings;
+
+public aspect SynchronizedAspect perthis(@this(Synchronized)) {
+
+// private static final Logger log = LogManager.getLogger(SynchronizedAspect.class);
+// private Lock objectLock = new ReentrantLock();
+// private static long timeout = 1800;
+// private static TimeUnit unit = TimeUnit.SECONDS;
+// private static boolean timeoutInitialized = false;
+
+// @SuppressWarnings({"rawtypes"})
+// private final static synchronized void initTimeout(Class cl) {
+// timeout = SynchronizedStaticAspect.aspectOf(cl).timeout;
+// unit = SynchronizedStaticAspect.aspectOf(cl).unit;
+// timeoutInitialized = true;
+// log.trace("timeout inialized with " + timeout + " " + unit);
+// }
+
+ pointcut synchronizedMethods() :
+ execution(@Synchronized !synchronized !static * *..*.*(..))
+ ;
+
+ pointcut synchronizedStaticMethods() :
+ execution(@Synchronized !synchronized static * *..*.*(..))
+ ;
+
+ pointcut ignoredSynchronized() :
+ execution(@Synchronized * *..*.*(..))
+ && !synchronizedMethods()
+ && !synchronizedStaticMethods()
+ ;
+
+ declare warning : ignoredSynchronized() :
+ "@Synchronized is ignored here";
+
+ declare warning :
+ (synchronizedStaticMethods() || synchronizedMethods())
+ && !@within(Synchronized) :
+ "@Synchronized is ignored here because @Synchronized for class is missing";
+
+ /**
+ * Uses the Lock class of Java 5 to put a synchronization wrapper around
+ * a method. Advantage of this Lock class is the posibility to use a
+ * timeout to avoid dead locks.
+ *
+ * @return the return value of the wrapped method
+ */
+ @SuppressAjWarnings({"adviceDidNotMatch"})
+ Object around() : synchronizedMethods() && @within(Synchronized) {
+return proceed();
+/*
+ if (!timeoutInitialized) {
+ initTimeout(thisJoinPointStaticPart.getSignature().getDeclaringType());
+ }
+ if (log.isTraceEnabled()) {
+ log.trace("synchronizing " + thisJoinPoint.getSignature().toShortString() + "...");
+ }
+ try {
+ if (objectLock.tryLock(timeout, unit)) {
+ if (log.isTraceEnabled()) {
+ log.trace("lock granted for "
+ + thisJoinPoint.getSignature().toShortString());
+ }
+ try {
+ return proceed();
+ } finally {
+ objectLock.unlock();
+ if (log.isTraceEnabled()) {
+ log.trace("lock released for "
+ + thisJoinPoint.getSignature().toShortString());
+ }
+ }
+ } else {
+ String msg = "can't get " + objectLock + " for "
+ + thisJoinPoint.getSignature().toShortString()
+ + " after " + timeout + " " + unit;
+ log.error(msg);
+ throw new RuntimeException(msg);
+ }
+ } catch (InterruptedException ie) {
+ String msg = "interrupted: "
+ + thisJoinPoint.getSignature().toShortString();
+ log.warn(msg, ie);
+ throw new RuntimeException(msg, ie);
+ }
+*/
+ }
+
+}
--- /dev/null
+package foo;
+
+/**
+ * For synchronization we synchronize each static method mark as @Synchronized
+ * by a ReentrantLock.
+ *
+ * @author <a href="boehm@javatux.de">oliver</a>
+ * @since 0.8
+ */
+import org.aspectj.lang.annotation.SuppressAjWarnings;
+
+public aspect SynchronizedStaticAspect pertypewithin(@Synchronized *) {
+
+/*
+ private static final Logger log = LogManager.getLogger(SynchronizedStaticAspect.class);
+ private Lock classLock = new ReentrantLock();
+ protected long timeout = 1800;
+ protected TimeUnit unit = TimeUnit.SECONDS;
+
+*/
+ /**
+ * This advice is used to get the timeout value for the wrapped static
+ * methods.
+ *
+ * @param t the annotation with the timeout value
+ */
+ before(Synchronized t) :
+ staticinitialization(@Synchronized *) && @annotation(t) {
+/*
+ this.timeout = t.timeout();
+ this.unit = t.unit();
+ if (log.isTraceEnabled()) {
+ log.trace("lock timeout for "
+ + thisJoinPointStaticPart.getSignature().getDeclaringType().getSimpleName()
+ + " set to " + this.timeout + " " + this.unit);
+ }
+*/
+ }
+
+
+private Log log = new Log();
+static class Log {
+ public boolean isTraceEnabled() { return true;}
+ public void trace(String s) {}
+ public void error(String s) {}
+ public void warn(String s,InterruptedException ie) {}
+
+}
+ClassLock classLock = new ClassLock();
+static class ClassLock {
+ public boolean tryLock(Object o, Object b) {
+return true;
+}
+public void unlock(){}
+}
+String timeout="";
+String unit="";
+ /**
+ * This is the synchronization wrapper for the static methods which are
+ * synchronized by a ReentrantLock class.
+ *
+ * @return the return value of the static method
+ */
+@SuppressAjWarnings
+ Object around() : SynchronizedAspect.synchronizedStaticMethods() {
+ if (log.isTraceEnabled()) {
+ log.trace("synchronizing " + thisJoinPointStaticPart.getSignature().toShortString() + "...");
+ }
+ try {
+ if (classLock.tryLock(timeout, unit)) {
+ if (log.isTraceEnabled()) {
+ log.trace("lock granted for "
+ + thisJoinPointStaticPart.getSignature().toShortString());
+ }
+ try {
+ return proceed();
+ } finally {
+ classLock.unlock();
+ if (log.isTraceEnabled()) {
+ log.trace("lock released for "
+ + thisJoinPointStaticPart.getSignature().toShortString());
+ }
+ }
+ } else {
+ String msg = "can't get " + classLock + " for "
+ + thisJoinPointStaticPart.getSignature().toShortString();
+ log.error(msg);
+ throw new RuntimeException(msg);
+ }
+ } catch (InterruptedException ie) {
+ String msg = "interrupted: "
+ + thisJoinPoint.getSignature().toShortString();
+ log.warn(msg, ie);
+ throw new RuntimeException(msg, ie);
+ }
+ }
+
+}
--- /dev/null
+package foo;
+
+//@ProfileMe
+//@ThreadSafe
+@Synchronized//(timeout = 2, unit = TimeUnit.SECONDS)
+public final class SynchronizedTest { //implements Runnable {
+
+
+ @Synchronized
+ public void incrementCounter() {
+/*
+ int n = counter;
+ log.debug("counter read (" + n + ")");
+ ThreadUtil.sleep();
+ n++;
+ log.debug("counter increased (" + n + ")");
+ ThreadUtil.sleep();
+ counter = n;
+ log.debug("counter written (" + n + ")");
+*/
+ }
+
+ public void run() {
+ // incrementCounter();
+ }
+
+}