How to migrate an Eclipse AspectJ project to IntelliJ IDEA - java

At my company, we are currently working with Eclipse for our Java projects.
As me and some other coworkers would rather use IntelliJ, we took a crack at migrating our projects and failed at getting AspectJ to work.
We are using Java 7 though the projects are written in Java 6 compatility.
Before trying it out we updated to the most recent version of IDEA (14.03).
The AspectJ version is 1.7.3.
Here are the steps we took:
import the project and dependencies into IntelliJ
download and install AspectJ
Under Settings -> Java Compiler: Use ajc compiler, delegate to javac (path to aspectjtools.jar is correct as the test button indicates)
Add AspectJ libs to Global Libraries (aspectjrt.jar, aspectjtools.jar, aspectjweaver.jar, and org.aspectj.matcher.jar)
Create AspectJ facet for the one module that is using AspectJ, leave all settings as is (no aspect path defined)
Add aspectjrt to project libraries
rebuild, make etc.
LogContext is just an empty interface. Classes that want a logger appended implement this interface.
This method is injected with AspectJ. Unfortunately I am not an expert with this and the guy who implemented it left the company, so I am stuck.
In order to check general functionality, we implemented a tiny project from scratch with just three classes with the same settings as above:
public interface LogContext {}
public aspect LogContextAspect {
public void LogContext.log() {
System.out.println("Log!");
}
}
public class Aspect implements LogContext {
public static void main(String[] args) {
Aspect aspect = new Aspect();
aspect.log();
}
}
The code actually executes fine and prints out the "Log!" message, but on make I get the following error:
Error:(4, 0) ajc: The type Aspect must implement the inherited abstract method LogContext.log()
What are we missing here? In order to migrate our projects, we need AspectJ to work.
The whole system is built with Java 6 compatibility but runs on Java 7.
Thanks for your help!
Sascha

I tried with IDEA 14.1.1 Ultimate and it works nicely, even though AspectJ support in IDEA is generally not as advanced as in Eclipse, even though all in all IDEA to me is superior. But for AspectJ I often use Eclipse.
I think it would be a good idea to "mavenise" your project. This way it would work in Eclipse and IDEA. In IDEA activate auto import for Maven changes to let Maven be the leading system and IDEA just follow its settings. This works well for my AspectJ projects. But in this case I set up your example manually (no Maven). After a few steps it works now. Along the way I did not see the error message you mentioned.
Edit: I use AspectJ 1.8.5, if that makes any difference.
Edit 2: I have tried with both compiler and runtime manually set to 1.7.3, it still works.

Related

How can I have separate debug and release versions of gradle project that pull in different versions of the same class?

I have two versions of the same Java class (same name / methods). Since it's Java, both .java files have the same name. I want to configure gradle in such a way that I can build a "debug" version of my application that pulls in one of these files, and a "production" version of my application that pulls in the other one. How would I go about doing this?
This class has only static methods. I don't ever want to make an instance of this class. I additionally don't want to add the overhead of an if statement in each of the methods on this class to check which version I'm in.
Following #JFabianMeier's answer you could use 4 projects:
with the production version class
with the debug version class
with code that uses either of the two, parameterized according to Migrating Maven profiles ... → Example 6. Mimicking the behavior of Maven profiles in Gradle. (I'm also a Maven guy and therefore can't tell you exactly how to do it in Gradle.)
a multi-project with 1./2./3. as sub[-]projects for building all of them in one go, maybe parameterized to build just 1.+ 3. or 2.+ 3.
Have you tried creating production and debug source directories/sets? According to the docs you can use multiple directories when specifying source directories in your source set. Try dropping the different versions of your class in their respective production/debug source directories.
I haven't tested myself (not sure about the syntax), but this is based on the Gradle's Java compilation documentation.
sourceSets {
// Could also name this production
main {
java {
srcDirs ['src/main/java', 'src/prod/java']
}
}
debug {
java {
srcDirs ['src/main/java', 'src/debug/java']
}
}
}
You could do the following:
Put the class into a separate project (so generate a separate jar from it)
Then you can have two different jars, for production and debugging
Then you can pull either one or the other jar in gradle depending on a parameter.
Alternatively, you could look into template engines like Velocity which allow you to generate source code during the build depending on variables and then compile it.
Android has a neat feature called Product Flavors. It lets you swap classes at compile time effortlessly and keep your project clean.
This post is very good to get a taste of it: https://android-developers.googleblog.com/2015/12/leveraging-product-flavors-in-android.html
And here is the full documentation: https://developer.android.com/studio/build/build-variants#product-flavors

Java 9 migration on intellij issues with module system

I am try to migrate my current project to be able to compile and run it on java 9. I am trying first to just move a java8 based project to java9 without not much effort which means not moving to jigsaw basically.
The project structure is something like
myjava-service [myjava-service-parent] parent-pom with the following modules
- myjava-service
- myjava-service-common
- myjava-service-test
it compiles perfectly with mvn clean package and it runs when I execute that fat.jar
the nightmare starts when I try to run it using intellij,to run on intellij i have to set the module I want to execute which is myjava-service but then apparently intellij understand it as java 9 module and well a lot of split packages issues, classes not found and other issues that I am struggling to fix, so my question is there a way to run the service on intellij under the java 9 environment without the new java module system being triggered somehow?
for the record issues like
java.lang.module.ResolutionException: Modules javax.annotation.api and annotations export package javax.annotation to module javax.el
So, apparently someone stepped into the same issue that I was facing, so what happens is that when your service start by a class which is not part of your sources (in my case my service is started by Starter class from the Vertx jar) then IDEA end up using the module path instead of class path. luckily Intellij team was quite helpful, follow up the ticket
https://youtrack.jetbrains.com/issue/IDEA-187390 , for the next version IDEA will abstain from using module path when there is no module-info file in sources.
Also for those who need desperately run a service in java 9 there's a work around which is basically create a Main class and Invoke it inside the class that starts your service, in my Case it looked like
public class Start {
public static void main(String[] args) {
Starter.main(args);
}
}

Using & checking Android Support Annotations with Maven or Eclipse (without Android Studio)

I would like to make use of a few the helpful annotations offered by Google's Android support-annotations library (http://tools.android.com/tech-docs/support-annotations) in a Java/Maven project.
I want the annotations to be verified at compile time using mvn or Eclipse, without resorting to Android Studio.
Is this possible at all?
I my pom.xml I've put the following:
<dependency>
<groupId>com.android.support</groupId>
<artifactId>support-annotations</artifactId>
<version>23.0.0</version>
<scope>provided</scope>
</dependency>
I am currently not using the android-maven-plugin as it is just a simple jar which doesn't rely on other Android libraries. Declaring the dependency allows me to use the annotations in my code. For example:
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
public class TestAnnot
{
#CallSuper
public void blah() { }
public void bleh(#NotNull String str) { }
}
This compiles fine in both Eclipse and through mvn. However, clear violations of the annotation's rules aren't being flagged by either. For example, nothing is currently stopping me from doing this:
public class SubTestAnnot
{
#Overrides
public void blah()
{
// not calling super.blah() even though I should
bleh(null); // calling bleh(String) with null even though that's not allowed
}
}
I've had a look at the source code of said library (look in <Android SDK path>/extras/android/m2repository/com/android/support/support-annotations/23.0.0) but it seems it only declares the annotations themselves but doesn't have code to verify them. So I'm assuming Google has implemented that separately, perhaps in one of the SDK components?
So, does anyone know how I can configure Maven and/or eclipse to actually check these annotations?
From here under "Enforcing Annotations"
When you're using Android Studio and IntelliJ, the IDE will flag calls where you are passing the wrong type of parameter to methods annotated with these annotations.
As of version 1.3.0-beta1 of the Gradle plugin, and with the Android M Preview platform tools installed, these checks are also checked/enforced on the command line by the "lint" gradle task. This is useful if you want to flag problems as part of your continuous integration server. NOTE: That does not incude the nullness annotations. All the other annotations in this document are checked by lint.)

Multiple main-methods for testing purposes in Netbeans 7.4 (project from Netbeans 7.2.1)

I recently switched from my older Netbeans version 7.2.1 to 7.4. I am working on a bigger project which uses only one main-entry point of course. However, for testing purposes I am using a second class which also contains a main-method. In my older Netbeans version I was able to Shift+F6 (Run File) and it did what it says: It runs the file because if has a valid main-method. With the never version of the IDE the program keeps telling me, that there is no main-method. This main-method is anything but special and the autocheck does not warn me either (Why wouldn't it? It is totally valid and worked in version 7.2.1).
Here is my testing class definition for the sake of completeness:
package Tests;
// various imports from surrounding project or external packages
public class TEST001 {
// variables and methods for further testing
public static void main(String[] args) throws IOException{
// [...]
}
}
Now, are there incompabilities between projects of Netbeans 7.2.1 to these of version 7.4 which might have caused this?
Or do I have to check a special option somewhere to allow the handling of multiple main-entry points? Which seems unlikely because running a file instead of the project seems to be permanent feature with its own user controls.
Or is this simply a bug?
Thank you for your suggestions.

Eclipse 3.5+ - Annotation processor: Generated classes cannot be imported

I am using a 3rd party annotation processor for generating meta-data code (.java files) from the annotated classes in my project.
I have successfully configured the processor through Eclipse (Properties -> Java Compiler -> Annotation Processing) and the code generation works fine (code is automatically created and generated). Also, Eclipse successfully auto-completes the generated classes and their fields, without any errors. Let's say that I have a class "some.package.Foo" and that the generated meta-data class is "some.package.Foo_". By the help of auto-completion, I can get the following code in the Eclipse editor, without any errors:
import some.package.Foo_;
...
public class Test {
void test() {
Foo_.someField = null; // try to access a field from the generated class Foo_
}
}
However, as soon as I actually build the project (or just save the file since Build automatically is enabled), I get the error which tells that "some.package.Foo_" cannot be resolved.
It seems like Eclipse is generating and compiling the some.package.Foo_ at the same time, or more likely.
I found two temporary solutions (which are practically hindering the use of the annotation processor in the first place):
Before each build of that generated classes, right click on every generated file go to Properties and uncheck the "Derived" tick. After that, I do the cleanup of the project and the imports are fine - there are no more errors. However, if I do the cleanup one more time, the errors again show up, because the generation of the files causes the "Derived" tick to be checked again (automatically). So this is really annoying and time-consuming.
I also uncheck the "Derived" tick
from all those files, and this time
I uncheck the "Derived" tick from
the source folder and packages which
contain those files. Then I disable
the annotation processor, and then
do the cleanup. There are no more
import errors, even if I do another
cleanup, but there is no benefit of
using the annotation processor,
because if I was to change something
which would update the model, I need
to turn the annotation processor
back on, and repeat this tedious
procedure to turn it off, after it
has generated the new version of
those files.
Is this a bug in Eclipse? If yes, is there a better workaround or quick-fix than the two I have stated above? If not, what should I try to solve the problem?
I also tried rearranging the order of the libraries on the build path and it doesn't help.
I assume that you are generating sources in the last processor round. This is not recommended way and leads exactly to the problem that you had.
Explanation is here: http://code.google.com/p/acris/wiki/CodeGenerationPlatform_Pitfall_Rounds
So the my advise is to generate sources in regular processing rounds and final round should be used just for notification that processing is over or something like that.
Hopefully this helps you.
I have a similar problem, and the only thing I've found is that it's the imports specifically that don't work, but the references in the class itself do work. The workaround I've used is to use the FQCN in all cases where the generated class is needed (except when the generated class is in the same package, since then the import is obviously not needed).
So to use your example, I'd do:
public class Test {
void test() {
some.package.Foo_.someField = null; // try to access a field from the generated class Foo_
}
}
My only guess then is that the eclipse compiler is processing the imports before doing the annotation processing, which imho must be a bug in eclipse.
I know this question is over a year old, so I'd be interested to know if you've found any other way to fix it.
We were experiencing a similar problem and apparently just solved it, so thought of sharing it at SO, in case it helps someone.
We are using:
Eclipse Indigo (Build id: 20120216-1857)
m2e Connector for maven
openJPA for static metamodel class generation
Our problem:
Say, we have a package named com.abc.xyz and an entity class in there named OurEntity. When we build the projects (JPA, EJB, EAR etc. all together with an mvn clean at the beginning) the metamodel classes get generated. And also get appropriately packaged within the PU jar. But when we try to import the generated metamodel class com.abc.xyz.OurEntity_, Eclipse cannot resolve it. OP apparently got past this point:-). Maven build failed, saying it could not resolve that class. Not much help from google except for a few bug reports such as this one: https://bugs.eclipse.org/bugs/show_bug.cgi?id=350378
That bug report said importing the whole package as opposed to the single class helped. So, tried that, but with no benefit. It also said (and so did David Heitzman) that using the fully qualified class name worked for them. That did not work either.
The solution:
Added the PU jar to Eclipse build path for the project that needed to use the metamodel classes. All of a sudden all the red underlines went away (not a surprise). But the fear was there might be two PUs in the same ear. But maven automagically took care of that.
As this rather old question got some attention without pointing to the very probable eclipse bug the OP was specifically asking for, I'd like to complement the above answers with a pointer to the eclipse bug tracker:
Cannot resolve import for generated class IF processing annotations with parameters referencing constants
The workarounds include
doing a wildcard import of the package defining the generated classes (i.e. import some.package.*;)
using the fully qualified name of your generated class, i.e. referring to some.package.Foo in your code and not using an import
switch to a newer Eclipse. This specific eclipse bug is resolved with Eclipse version 4.4 (aka Luna).

Categories