How can I replace the compiler in Eclipse with ajc so that it compiles as I edit?
You are going to have to be more specific about what you are looking to have happen. I think the term you are looking for is eager parsing. In JDT, files are not compiled as you type, but rather there is a reconcile occurring in the background that does everything except write the bytecode to disk.
I am assuming that you have AJDT installed and your project is an AspectJ project. AJDT largely provides the same feature, except that it doesn't perform eager parsing inside of pointcuts and declare statements. It also will not do eager matching of pointcuts.
Are you seeing some different behavior?
Related
I´m implementing a library in Kotlin that it will be used from Java.
It would be possible to create an annotation and AOP code in Kotlin, and then being used from Java.+
If that possible a documentation or example it would be awesome. I cannot find anything with that interoperability.
Regards.
As for the annotation, there should not be any problem implementing it in Kotlin.
As for the aspect, when compiled with the Kotlin compiler it shall end up being a regular JVM class with all the necessary #AspectJ annotations, but it will not be an aspect because it was not compiled by the AspectJ compiler which as of today only understands Java source code.
If you use such an "unfinished" aspect via LTW (load-time weaving), the AspectJ weaver can finish it into an aspect while it is being loaded, so that scenario should work.
In the case of trying to use the unfinished aspect for compile-time or binary weaving against Java (or Kotlin) target classes, an intermediate step to finish the unfinished aspect using the AspectJ compiler would be necessary, but I never tried that and do not know if it is even possible. It would be interesting to try. I do not speak Kotlin, but maybe it would be fun to try if you have something for me to start with like a sample project, ideally built with Maven. If there is any way to pull this off, we would end up using the AspectJ Maven plugin for just like #dreamcrash suggested, just in a different way.
BTW, I need more information from you about what you mean by "use from Java". Please elaborate.
Update: I just gave it a quick try:
Annotation + aspect both in Kotlin
Compile with Kotlin compiler into my-aspect.jar, aspectjrt.jar on the class path
Package Kotlin classes into a JAR
Java class using annotation from Kotlin aspect JAR
Compile with ajc, my-aspect.jar on the inpath and aspectjrt.jar and kotlin-stdlib.jar on the class path.
Result is e.g. in bin directory, both the Java class and the two Kotlin classes from the JAR, but the aspect this time finished by ajc (bigger class file than original).
Run Java program with bin folder, aspectjrt.jar and kotlin-stdlib.jar on the class path.
Works nicely, aspect kicks in.
The only step remaining is to "mavenise" this in connection with AspectJ Maven plugin, which should be fairly easy. But the answer to your question is: Yes, you can implement an aspect in Kotlin and use it combined with Java target classes. The downside of course is that you need the Kotlin standard library on the class path, not just the AspectJ runtime as usual.
Update 2: I created a Maven multi-module playground project for myself and for your convenience. Just clone my GitHub repository, then build and run according to the read-me file.
As far as I understand, Lombok uses Java's Annotation Processors to generate additional methods.
With Maven 3.5 it works perfectly without adding any additional configuration, just add dependecy to Lombok and put some annotations like #Getter, #Setter.
However, if I open this project in IntelliJ IDEA 2018.2, all usages of generated getters/setters are highlighted as errors. I have Annotation Processing turned on, I tried to built project in IntelliJ or build in Maven and then use in IntelliJ, but it still requires Lombok Plugin to avoid false errors.
Is it some kind of bug? Error in workflow? Or maybe Lombok is using not only Annotation Processors, but some other stuff I didn't know and that's why IntelliJ + javac cannot figure out how to deal with it? It would be strange as javac itself compiles those files without errors
I know there are many questions "I have errors while using Lombok" and answers like "use the plugin". I'm not asking if I should use plugin, but why I should use it, why IntelliJ cannot handle it without plugin while javac does
IntelliJ's code analysis engine does not use javac or run annotation processors. Instead, IntelliJ uses its own Java parser and reference resolution logic, and builds its own code model. The Lombok plugin extends the code model to provide information about declarations generated by the Lombok annotation processor.
It's because IDEA syntax highlighter uses internal Java parser. If IDEA used just javac, then it wouldn't be able to highlight syntax errors as you type. It also gives much better hints about wrong code, so each Java construct, feature or annotation must be implemented by JetBrains team or there's plugin for it like in this case.
Annotation processing option is just for building project which is done via javac, but it's not for syntax highlighting.
Ale IDEs use lombok plugin be it intelij-idea or eclipse.
javac works fine with it - but remember that it works when for example you build you project with mvn clean package.
Then when you have your IDE - it works differntly - the code is not processed like in build task.
The plugin make it know to IDE what is this annotation and what code it generates underhood without need of javac.
I am trying to understand how Aspect works. I come from a C/C++ background where magic never happens.
I understand that you can annotate some functions with #Aspect then write down the Aspect implementation and so on. But, how (and at what time) does the new code get generated?
Assuming I have no editor. I compile java classes using javacc command
that will generate .class files. Now, assume that the java files are annotated using Aspect. Shouldn't I then compile the .class files again with Aspect somehow to generate another set of .class files?
If my understanding is correct, how is this dual compilation step done in maven? or spring? I found many tutorial that will tell you what to add here and there to get things working but no tutorial explains how these things are actually working.
It is easy to tell that you are a C++ guy. There is no such thing as javacc (if you are not talking about the Java Parser Generator of the same name) but the Java Compiler is called javac. ;-)
As Philipp Wendler already pointed out, Eclipse is not just an IDE, it is an organisation similar to Apache, and AspectJ has been adopted many years ago as one of its projects. This has also the advantage that AJDT (AspectJ Development Tools) for Eclipse IDE are sort of the best AspectJ support you can get for any IDE, sadly including my favourite IntelliJ IDEA which is superior to Eclipse IDE in almost all respects except its AspectJ support being rather mediocre.
So much for the minor topics. Now as for your main question, it is not really suited for Stack Overflow because it is rather a forum question, not about a concrete programming problem requiring a solution. Anyway, I love AspectJ and will answer briefly:
AspectJ has its own compiler ajc which is basically an enhanced version of the Eclipse Java Compiler ejc, i.e. it can be used to compile normal Java files as well as aspects in native AspectJ syntax or in #AspectJ style annotation-based syntax. No matter which way you weave your aspects, e.g.
build aspect + Java code with ajc from scratch (compile-time weaving),
build only aspects with ajc and Java code with javac, ejc or any other Java compiler, then
weave aspects into Java class files via ajc (post-compile or binary weaving) or
weave aspects into Java class files at runtime during class-loading with a Java agent called the AspectJ Weaver (load-time weaving, LTW),
What AspectJ does is always pretty much the same: It modifies Java byte code by weaving aspect code into it. In case 1 you just get one set of class files directly from ajc. Case 2.1 creates additional, new class files. Case 2.2 just creates new byte code in memory directly in the JVM.
I see from the javadoc that the #SuppressWarnings annotation applies to
TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE
targets. Why does it not also apply to PACKAGE?
I have some generated code which contains some raw types warnings. I'd like to be able to add a package-info.java file for the generated classes (in a separate physical directory but the same java package) which tells eclipse to ignore any raw types warnings emanating from the generated classes in package.
Why is this not supported? Is there an alternate way of suppressing a warning in an entire package?
The reason that suppressing warnings at the package level is not allowed was explained in the response to an old bug report (Status - Closed, Will Not Fix): Allow SuppressWarnings to be specified at the package level.
The warnings actually indicates potential problems in the
generated code.
Currently, SuppressWarnings have the desirable property of
only affecting lexically nested code. This means that you
can immediately see if a warning might be suppressed in
code you're reading.
This proposal would violate this property to solve an uncommon
problem which in most cases can be worked around.
There are a couple of work arounds suggested in that response as well.
compile the generated code by itself using -source 1.4 and -target 5.
request an updated version of javacc which either uses suppresswarnings
or doesn't generate code which causes warnings.
I think the first suggestion, putting the generated code in its own project, should work for you. The second suggestion looks like its more specific to the problem in the bug report. I don't know if you're using javacc or not.
Good question. Probably this will be fixed by Oracle in future.
But now I can suggest you the following. Put all generated code to separate project. BTW it is common practice. Then configure this project to be patient to warnings. For example in eclipse you can open project properties/Java Compiler/ Errors/Warings, select "enable project specific settings" and disable all warnings.
Some of my colleagues lack discipline and not always write documentation of their classes(not always = never). I was trying to force them to write documentation by setting project warnings for missing comment javadocs. We got two source folders 'src' and 'tests' - obviously not all #Test methods needs documentation and this warning there is redundant. But now all undocumented tests got these annoying warnings, the project got hundreds of warnings and I'm afraid that some real dangerous warnings will be missed(because there are hundreds of useless ones).
How to set warnings only on the 'src' folder, and ignore the warnings on 'tests' folder?
I'm afraid there is no setting to disable missing javadoc validation strictly for Test classes/methods. There even was a suggestion posted on Eclipse bugzilla here but eventually it came to an dead end.
The only, nonelegant way of solving this issue is by annotating those test methods with #SuppressWarnings("javadoc") annotation.