I have implemented an AnnotationProcessor that picks up class annotations that take a string argument. The string argument is an expression in a domain-specific language, which the annotation processor will use to compile a class file.
I create a small test project to try this out. The behaviour I see is this:
I can successfully build the project using maven
I can successfully run the project from within intellij
Despite the project RUNNING in intellij, the generated class is not recognised in the editor ("Cannot resolve class '...'"), and intelli-sense does not work, either.
I've tried to find the issue and found:
the class file that is being generated is being created in target/classes/package/name/KlassName.class (this is the location that the Filer::createClassFile method picks, I'd have expected this to go to some separate directory though).
if I'd create a java source file during annotation processing (using Filer::createSourceFile), intellij would have no problem. However, I can't do that, since the compiler is a library that really must create classes directly.
I have two guesses about what a solution might look like:
This problem might stem from intellij not looking inside target/classes when type checking in the editor window.
The class files should be generated in a separate directory instead. If so, what is the setting to fix that?
I have reproduced this issue using intellij IDEA 2016.2.1 and intellij IDEA 2017.2 EAP.
Related
I am writing a java program with an open source library using Eclipse and I am observing my IDE suggestions as follows. I added the library to my project by importing jar from IDE.
As you can see in the image, it shows me parameter names as srg0, arg1,..
However, in the source code of the library in github, it uses different variable names such as P, N, r.
I have observed in some cases IDE shows the same name that is used in the source.
I am curious on how IDE shows parameter name in such cases. How does the IDE pick parameter names to show here?
Either the references class would have had to be compiled using the -parameter compiler flag (see https://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html)
Or you need to attach the source of the library to the library jar
I'm developing an Eclipse plugin in which I want to overwrite the functionality of a method contained in a class that is in the Eclipse library.
What I've tried so far is creating an identical (same package and file names) file in my plugin source, and making the changes I want there. Then, I set the build path order such that my source is above the Plug-in Dependencies. Based on my limited understanding, this should mean that when Java looks for that class, it should use mine over the one in the library.
However, this is not working. The behavior that I want to override is not changing, and I don't see the print statements I put in my code either.
How can I "replace" a class in the Eclipse library with one of my own?
I did it once (not proud of it :-)) in the following way:
Import the plugin you wish to hack by Import->Plugin Development->Plug-ins and Fragments (Import as Projects with source folders).
Set the project to build automatically, edit the file and find its resulting class file.
Open the jar of the plugin (the one containing its class files), inject your class file instead of the original one.
If jar file is signed remove all signature information from MANIFEST.MF (and maybe other files).
I admit it's ugly but it's the best way I've found.
I ended up using the JVM JavaAgent to achieve this, by overriding the class loader and loading in my own class to replace the one in the library.
This was a useful tutorial for me: https://stackoverflow.com/a/11898653/634324
My goal is to add some source code to existing class using annotations.
First, I create an annotation and then I implemented a AbstractProcessor Class.
After that I create the javax.annotation.processing.Processor file and I generate the JAR file using the export eclipse option.
When I use my jar in other project I have the following error:
Internal compiler error: java.lang.NoClassDefFoundError: com/sun/source/util/Trees at org.xxx.preprocessor.ActionProcessor.init(ActionProcessor.java:44)
And the mentioned line is like the joined picture:
I want to use tree in order to get the compilation unit and add some code to my annotated function.
So in the first time I don't know how to fix this problem, or another way to do this.
You wrote an AP tool which is based on Sun internal code but run it inside of the Eclipse IDE. Eclipse comes with it's own Java compiler, so you don't have access to internal Java classes anymore.
I suggest to look at Project Lombok which has the exact same problem and look at their solution. The source hides behind the "Contribute" link: https://github.com/rzwitserloot/lombok
In the src/ folder is a folder eclipseAgent/ which should get you started.
I have a class BaseLoginDialog under a dependency which needs to be modified as it is not extendable out of the box. For this reason, I have created another file BaseLoginDialog under my project's module with the same package path as the original BaseLoginDialog. After adding some new methods in my own local BaseLoginDialog, I cannot use them anywhere in my project without IDEA complaining about the method not being declared. However, the project still compiles and the methods work fine on runtime. If I click the import to browse to the file, IntelliJ still links to the old file but it seems to correctly compile with the new one.
How can I go about fixing this issue? Always having error lines and red markers everywhere makes it confusing when coding.
Some background:
The project uses Gradle for the dependencies and compilation. Compiling and running works both with Gradle and with the IntelliJ run operation, it is only the errors being incorrectly displayed that is an issue.
The Grade file adds the required libraries as dependencies. Even though Gradle has both the source and class files, opening a file imported through Gradle still links to the class files. To get around this I also added the required files as sources under Libraries.
Any help would be appreciated, thanks!
EDIT:
Switched to use a Maven repo on the project, now I don't need to additionally add libraries anymore but this problem still persists.
If two classes of the same name and package exists in the classpath of an application, it's the one that is contained in the first dependency on the command line that gets used.
In IntelliJ, you can reorder dependencies, so you can put your local dependency before the other library. I'm not sure if that works with gradle projects, however.
But I don't think that's a good practice? Why can't you put the extra methods in a subclass, e.g. EnhancedLoginDialog, and use that one?
Or, if the original library is open source, fork it, make the changes and install it as a custom version, e.g. dialogs-1.0-CUSTOM-1.jar, and use this version in your project. And while you're at it, create a pull request for the library's maintainer to include your fixes in the next version :-)
I have resolved the issue.
The file I was copying into my local files was BaseLoginDialog. The file showing errors was my NewLoginDialog which extends LoginDialog which extends BaseLoginDialog. It seems that when IntelliJ goes to my NewLoginDialog, it sees that I have extended LoginDialog. Therefore it jumps into the library files and finds that LoginDialog extends BaseLoginDialog, now when it goes to find BaseLoginDialog, it uses the library files and ignores my local copy of BaseLoginDialog.
Essentially, once IntelliJ branches into a library, it does not move back out when looking for additional files if it can already find it inside the library.
To solve this issue, I simply also copied LoginDialog locally, even though it is identical (simply branched it and did not change anything). Now IntelliJ finds LoginDialog in my local files and as a result also finds BaseLoginDialog locally.
Hope this helps anyone having the same problem in the future.
I've extracted a bunch of functionality from my app into a library. The problem is I'd like to make use of the library classes in both production code and tests. The issue is that my app, my library, and the test code are separate modules, so both the app code and the test code need to depend on the library. When I try to compile the test module, I get the following error:
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.IllegalArgumentException: already added: (some class)
It's cryptic, but it's trying to say that I've tried to add the same class to the .dex file more than once. It's not too surprising since the test code depends on the library code and on the app at compile time, which also depends on the library at compile time. How do I set up my dependencies (or change my code) to avoid this?
NOTE: I'm using IntelliJ IDEA 10.5 CE, so I use their terminology, but I think the problem is at least conceptually IDE-agnostic.
It's a bug in IDEA, we've submitted an issue for it, please watch/vote.
Hi I feel the same jar is added multiple times using different ways.
There is two ways of putting jar in your project
Right on Project->Properties->Java Build Path->Add Jars->
Right on Project->Properties->Java Build Path->Add External jars->
first remove all jars. inside your application folder create a folder there put all the required jars.
Right on Project->Properties->Java Build Path->Add Jars-> select your project folder and select the jar file
Thanks
Deepak