Why does aspect wants return type int? - eclipse

The following aspect give me a "This method must return a result type of int"
package CH.ifa.draw.framework;
public aspect Trace {
after() returning (ConnectionFigure figure): call(*.new(..)) {
System.out.println("test");
}
}
I'm expecting void as the result type.
Update
I expect that this pointcut is called for every creation a class that implement de ConnectionFigure interface
Update 2
package CH.ifa.draw.framework;
public aspect Trace {
after(): call(ConnectionFigure+.new(..)) {
System.out.println("trace creation figure");
}
}

Your aspect advice is incorrect, or at least incomplete. The returning (ConnectionFigure figure) should be given you an error since the parameter is unbound in the pointcut expression. Try removiong that component and seeing if it works for you.

Related

Get Annotation Parameter with AspectJ

I read many question in this forum but nothing works.
public #interface MyAnnotation {
String value() default "";
Class[] exceptionList;
}
#MyAnnotation(value="hello", exceptionList={TimeOutException.class})
public void method() {}
#Aspect
public class MyAspect {
#Around("#annotation(MyAnnotation)")
public Object handle(ProceedingJoinPoint joinPoint, MyAnnotation myAnnotation) {
System.out.println(myAnnotation.exceptionList); // should print out TimeOutException
}
}
How can I get the value and the exceptionList of the #MyAnnotation while executing the advice?
I'm using Spring 4.0.6, AspectJ 1.7.4
The solution for this is making sure the advice method's parameter name match the parameter name in AspectJ expression. In my case, the advice method should look like this:
#Aspect
public class MyAspect {
#Around("#annotation(myAnnotation)")
public Object handle(ProceedingJoinPoint joinPoint, MyAnnotation myAnnotation) {
System.out.println(myAnnotation.exceptionList); // should print out TimeOutException
}
}
You are already almost there. Probably.
You are using the correct way to retrieve the annotation, so you have the values available.
Your problem - if I interpret the very minimalistic problem description(!) you only provide via the comment in your code snippet(!) correctly - is the (wrong) assumption that sticking an array of the type Class into System.out.println() will print out the names of the Classes it contains. It does not. Instead it prints information about the reference:
[Ljava.lang.Class;#15db9742
If you want the names of the Classes, you will have to iterate over the elements of that array and use .getName(), .getSimpleName() or one of the other name providing methods of Class.
Further information on how to print elements of an array is here:
What's the simplest way to print a Java array?
Granted, this whole answer could be entirely besides the point if the problem is that you are getting null values from the annotation fields. But since you have not provided an adequate problem description ("nothing works" is not a problem description!), we can only guess at what your problem is.

Is there a way to have a get only (no set) in a typescript interface?

I have a case where I want to have just a get in the interface, no set. Is there a way to do that?
If not, we can implement a set and throw an exception if it is called. But it's cleaner if we can have just a get.
At present I have:
export interface IElement {
type : TYPE;
}
export class Element implements IElement {
public get type () : TYPE {
return TYPE.UNDEFINED;
}
public set type (type : TYPE) {
this.type = type;
}
}
I would like to have my interface & class be:
export class Element implements IElement {
public get type () : TYPE {
return TYPE.UNDEFINED;
}
}
TypeScript interfaces cannot currently define a property as read-only. If it's important to prevent, you'll need to throw an exception/error at runtime to prevent sets within the setter for the property.
The compiler doesn't require that you implement the get and a set though. You can just implement the get for example. However, at runtime, it won't be caught.

Inter Type Declaration on Compiled Class File

Is it possible to do Inter Type Declarations with AspectJ on Compiled Class Files at Load Time Weaving?
As an example: I compile some Groovy code and want to add fields or methods with IDT.
Update:
Oh my goodness, you do not need reflection to access members or execute methods. Eclipse shows errors in the editor, but you may just ignore them, the code compiles and runs fine anyway. So the aspect is really much more strightforward and simple:
public aspect LTWAspect {
public static String Application.staticField = "value of static field";
public String Application.normalField = "value of normal field";
public void Application.myMethod() {
System.out.println(normalField);
}
void around() : execution(void Application.main(..)) {
System.out.println("around before");
proceed();
System.out.println("around after");
System.out.println(Application.staticField);
new Application().myMethod();
}
}
Original answer:
Yes, but you have a hen-and-egg problem there, i.e. you cannot just reference the newly introduced fields from your LTW aspect code without reflection. (The last sentence is not true, see update above.) Plus, in order to make your LTW aspect compile, you need the classes to be woven on the project's build path so as to be able to reference them. Example:
Java project
public class Application {
public static void main(String[] args) {
System.out.println("main");
}
}
AspectJ project
import org.aspectj.lang.SoftException;
public aspect LTWAspect {
public static String Application.staticField = "value of static field";
public String Application.normalField = "value of normal field";
public void Application.myMethod() {
try {
System.out.println(Application.class.getDeclaredField("normalField").get(this));
} catch (Exception e) {
throw new SoftException(e);
}
}
void around() : execution(void Application.main(..)) {
System.out.println("around before");
proceed();
System.out.println("around after");
try {
System.out.println(Application.class.getDeclaredField("staticField").get(null));
Application.class.getDeclaredMethod("myMethod", null).invoke(new Application());
} catch (Exception e) {
throw new SoftException(e);
}
}
}
So, e.g. in Eclipse you need to put the Java project on the AspectJ project's build path under "Projects" because only then it can see Java class Application on which you want to declare members. After compilation you just start the Java project and do LTW on the aspect project (don't forget an aop-ajc.xml referencing LTWAspect).
In my example above I declare a static member, a non-static ("normal") member and a non-static method. My advice prints the static member and calls the non-static method, both via reflection. The non-static method then prints the non-static member, again via reflection. This is not nice, but it works and proves the ITD in combination with LTW is possible. There might be a more elegant way, but if so I am unaware of it. (Update: There is a more elegant way: Just ignore the errors marked by Eclipse IDE, see above.)
Program output
around before
main
around after
value of static field
value of normal field

How to get the caller method information from Around advise

ThisJoinPoint can only get the current method information, anyway to get the caller method information?
You can try the special variable thisEnclosingJoinPointStaticPart which holds the static part of the enclosing JoinPoint.
Mentioned here (example) and here (docs)
Or if using annotation-based AspectJ, pass following to the advice method's parameters, e.g.:
#Before("call( /* your pointcut definition */ )")
public void myCall(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart)
{
// ...
}
Mentioned here
#Aspect
public class LoggingAspect {
#Before(value = "execution(public * findAll())")
public void beforeAdvice(JoinPoint pp){
System.out.println("before advice called ....get calling method Signature"+pp.getSignature());
System.out.println("before advice called ....get calling method name"+pp.getSignature().getName());
}
}

Autofac: Injected collection is not empty (contains one item)

I'm using Autofac 2.4.4.705.
The output of the following code is: 1 (which means the resolved collection contains one item. I thought it should be empty)
class Program
{
static void Main(string[] args)
{
var builder = new Autofac.ContainerBuilder();
builder.RegisterModule(new AutofacModule());
using (var container = builder.Build())
{
var x = container.Resolve<ObservableCollection<A>>();
Console.WriteLine(x.Count);
}
}
}
class A
{
}
class AutofacModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly());
builder.RegisterGeneric(typeof(ObservableCollection<>))
.As(typeof(ObservableCollection<>));
}
}
It seems the issue is cause by:
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly());
If I remove it from AutofacModule, then the output is 0.
Any ideas?
Thanks
Update:
Ah, I think I understand now. Autofac thought I want to resolve all types of A, and there is one type of A in this example (A itself), so the ObservableCollection contains one item. I previously thought only IEnumerable<> has this behavior. But it seems subtypes of IEnumerable<> also have this behavior.
But sometimes what I really want is to inject an collection, for example, sometime I need to inject DispacherNotifiedObservableCollection into my ViewModels. Any workarounds?
Update 2:
Based on the answer of Nicholas Blumhardt, I changed my code to:
builder.RegisterGeneric(typeof(ExtendedObservableCollection<>))
.As(typeof(IObservableCollection<>))
.UsingConstructor();
public interface IObservableCollection<T> :
IList<T>, ICollection<T>, IEnumerable<T>, INotifyCollectionChanged, INotifyPropertyChanged
{
void AddRange(IEnumerable<T> list);
void Sort<TKey>(Func<T, TKey> keySelector, System.ComponentModel.ListSortDirection direction);
void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer);
}
Now everything works fine. Thanks!
The behavior you're seeing is a result of the ObservableCollection type having a constructor that accepts IEnumerable.
You can change this to use the default constructor using the UsingConstructor() option.
ObservableCollection itself might not be a very good contract to depend on though- it is a bit unclear what the semantics should generally be. Wrapping it in a specialized component with it's own interface is the better option.