Make project using Maven - intellij-idea

I'm working on a multi-project (multi-module) Maven project that uses a non-standard DSL compiler. It uses a Maven plugin that runs during Maven's compile phase, for just one project in the set.
I tried importing my code as a "Maven" project in IntelliJ IDEA, but IntelliJ doesn't seem to recognize that I have a custom compiler for my project; the compile fails.
What I want is to tell IntelliJ, "You can use your normal Java compiler to Make most projects, but for this one project, you should invoke Maven and let it do its thing."
Is that possible?

Related

IntelliJ Recompiling classes it could get from target/

I have a multi-module project that uses maven. Is there a way I can point IntelliJ to maven target/ folder so when I start Debug it won't rebuild the project from scratch and re-upload a whole project via JRebel all over again.
Basically, use target/ as a build folder. Changing compile output path didn't work as I expected it to not compile classes that were compiled by mvn already.
The IntelliJ Run/Debug configurations can specify which actions happen before launching the application.
By default for say web applications, this would display
Build
Build x artifact
You may remove both entries if you are happy with building via maven before launching the application.
Regarding the JRebel side of it - it should certainly not be updating the classes on the second compile assuming nothing changed. The classes have their hashes checked before a reload. This is assuming maven and IntelliJ are using the default javac compiler. If either is configured to use ecj compiler, it's best to let JRebel only see classes built with the same compiler.

Will intellij idea "mvn install" automatically when make the project?

I'd like to know what will Intellij IDEA do with my Maven project when I click "build the project"?
How will Intellij build the project with Maven?
Intellij IDEA will not automatically do a make install when you do a Build Project. In order to do that, proceed as follows:
Under Maven Projects tab (usually on the right hand side), select the goals you want Intellij to run after a Build -> Make Project and then right click and select the trigger (for instance in the above snapshot, the trigger was chosen as 'Execute After Make'. You can choose whatever you wish).
After doing this a Build -> Make Project will run a mvn clean install as well.
IntelliJ's build system refers to the Maven ecosystem for some hints, but at the end of the day it is a separate build system.
In IntellIJ, you have a Project, with many Modules. These are both IntelliJ concepts.
An IntelliJ Module has a responsibility to understand what are its dependencies and libraries. This can be done purely with IntelliJ semantic, or IntelliJ can allow some other build system to declare the dependencies and libraries. That is to say: the IntelliJ Module can be based on a Maven pom.xml or Gradle's build.gradle.
When you click "Make" on an IntelliJ Java Module: IntelliJ will check which libraries your Module asks for, and also resolve the dependencies of your Module to work out which libraries its dependent Modules ask for.
Once the libraries are known: IntelliJ will invoke Javac or the Eclipse Compiler (whichever you've configured as your Java compiler) with all those libraries on the classpath. And it will output a jar, not a Maven artefact.
IntelliJ Make will not run a mvn compile or similar (unless you configure it to explicitly, as per #Ashutosh Jindal's answer.
Why would IntelliJ use its own, separate build system, when you've provided an authoritative definition for how you'd like to build your project? I can imagine various reasons:
Maven generally just outputs an artefact (sources and binary jars, and a pom.xml), whereas IntelliJ needs additional semantic and indexes to provide all its IDE intelligence. It makes sense to perform the indexing process alongside the compile, since: if you do the compile incrementally, you can understand incrementally which indexes are dirtied also.
The IDE benefits from being involved in the compilation process. For example: IntelliJ can do "continue on error" builds using the Eclipse compiler. Additionally, the Eclipse compiler can be used to compile only those files which have changed (IDEs watch you as you code, so they know very well which files are dirtied). I have heard that Maven does incremental compile, but I don't know how its performance compares.
In order to support a variety of build systems (Ant, Maven, Gradle): the easiest engineering choice for IntelliJ is to rely on the minimum possible amount of domain-specific semantic, and use that to inform one IntelliJ-specific build system. This allows them to re-use a large amount of code, and have few domain-specific differences.

Getting contents and natures of all projects in a Maven build

Currently I'm working on a Maven plugin that should generate files in all projects (OSGi bundles) that have a certain Eclipse project nature.
How can I access the contents of the projects included in the build and the project natures by using the Maven API?
Maven is a standalone build tool, not an Eclipse plugin. You cannot access Eclipse project settings from core Maven API.
Eclipse supports Maven with the M2E Eclipse plugin. It is possible to write M2E extensions and in the extension you can query the project natures via the functions of AbstractProjectConfigurator class.
However, M2E extensions will not run when you compile your code in the command line. I suggest that you choose one of the followings:
Write an Eclipse plugin that generates the source code into the src folder of the maven project. Code generation should be started by the user manually (selecting a context menu in the project or something).
Avoid using Eclipse project natures and solve your questions based on analyzing the source and pom of your project.
If you need to react on certain aspects in the source code like it looks from the thread with Balazs then you can simply write an ordinary maven plugin and include it in the parent pom. It will then run in every project and can analyze the code and react based on it.

IntelliJ IDEA with multiple gradle subprojects

I'm working on multiple Gradle projects with internal and external dependencies, and so far I am happy that thanks to Gradle's dependency management I can modify a library project without affecting every application that uses the library.
When I need to modify a library project and test it using an application project that uses it, I need to do the following,
Modify the library project and commit to SCM
Trigger CI to build the library project and push it to my Gradle repository
Update the application project's build.properties to refer to the new version of library project
Iterate the above steps until everything works and there is no bug
So it became quite combersome now. Can I configure IntelliJ IDEA so that
All my Gradle projects are in one window, like the screenshot below, which is Twitter's Finagle imported using its pom.xml. Sadly IntelliJ's JetGradle plugin doesn't seem to understand Gradle subprojects.
When build.properties's dependencies are my subprojects, read dependency from local snapshot, otherwise download them from the Gradle repository
Thanks.
If you want to open all projects in a single IDEA window, you'll have to aggregate them into a multi-project build, at least until IDEA 13 hits the market. Before IDEA 13, it's better to use Gradle's IDEA integration. Once you have a multi-project build, all you need to do is to add allprojects { apply plugin: "idea" } to the root build script, run gradle (cleanIdea) idea, then open the generated IDEA project.
Currently in IntelliJ IDEA 2019.2 you can add the gradle subprojects like so
Open Gradle Tool Window via View > Tool Windows > Gradle menu
Click on "Link Gradle Project" button (the plus sign)
Select the build.gradle file corresponding to the subproject
Go to File > Project Structure > Modules > NameOfSubproject
Navigate to main/java and click on Mark as: Sources
Mark the main/resources as Resources
Restart IntelliJ IDEA
The sources of the subproject will be recognized by IntelliJ and you can use Navigate Class action for the classes in the subproject

Binary output and testing for Eclipse plugins

I am developing an Eclipse plugin and I use maven to coordinate my source structure. In order to compile the plugin I use the tycho extension for maven. However, I was wondering how to execute unitests.
I want to use the surefire plugin for testing as I additionally use a sonar server for source code quality management. Unitests are applyed if I use eclipse-test-plugin as package target. However, I want to make use of the default surefire plugin for applying unitests.
Now I figured out that the src/test/java that contains my unittest packages is read and compiled correctly but written into the wrong output folder. I need to have the tests in target/test-classes. However they are compiled to target/classes.
As I am new to Eclipse plugin development and maven I could not find out how to write the tests to the correct output folder. I've already tried adding and and changing the build.properties of the eclipse-plugin project. It works also fine for other projects that aren't plugin projects and do not make use of tycho.
Any help appreciated.
Regards,
Florian
Unlike standard maven projects, the convention for eclipse plugins/OSGi bundles is to have tests reside in separate projects. This is because there is no such thing as a maven dependency scope "test" in OSGi.
Thus keeping your tests inside the same project as your code under test would force you to mix up test code/dependencies an productive code/dependencies.
As you mentioned, Tycho provides a separate maven packaging type "eclipse-test-plugin" which you should use for dedicated test plugins/fragments. See https://docs.sonatype.org/display/TYCHO/PackagingTypes
There is no support in Tycho for plain unit tests residing in the same project.