= Using IntelliJ

:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

This section describes how to install and setup JetBrains' IntelliJ IDEA, then how to import an application into IntelliJ and run it.


== Installing and Importing

This section covers installation and setup.
These notes/screenshots were prepared using IntelliJ IDEA Community Edition 2023.1.2, but is believed to be compatible with more recent versions/other editions of the IDE.

=== Download and Install

https://www.jetbrains.com/idea/download/[Download] latest version of IntelliJ Community Edition, and install.


=== Import Project

In IntelliJ a project can contain multiple modules; these need not be physically located together.

Download either the xref:docs:starters:helloworld.adoc[HelloWorld] or xref:docs:starters:simpleapp.adoc[SimpleApp] starter app to your filesystem.

From the welcome screen, select "open project":

image::015-import-project/010-welcome.png[width="700px"]

Navigate to the top-level pom.xml of the starter app:

image::015-import-project/020-import-pom.png[width="500px"]

Acknowledge that the containing directory can be trusted:

image::015-import-project/025-trust-directory.png[width=500]

Project opened:

image::015-import-project/030-imported.png[width="1000px"]


Use menu:File[Project Structure] to confirm that JDK 11 is configured:

image::015-import-project/040-project-structure.png[width="800px"]


== Configuring

//include::partial$UNUSED/file-templates.adoc[leveloffset=+2]
//include::partial$UNUSED/live-templates.adoc[leveloffset=+2]
//include::partial$UNUSED/coding-standards.adoc[leveloffset=+2]

=== Compiler Settings

There are a number of compiler settings that influence the compiler.
We highly recommend you set these.

On the *Compiler* Settings page, ensure that `build automatically` is enabled, and optionally `compile independent modules in parallel`.
You might also want to increase the heap size, eg to 2048.

.IntelliJ Compiler Settings
image::040-other-settings-compiler/010-build-automatically.png[width="1000px"]


On the *Annotation Processors* page, confirm that these are enabled for all modules with the `... sources directory` correctly defined.
(In most recent editions of IntelliJ, this is detected automatically; no changes are required).

.IntelliJ Annotation Processor Settings
image::040-other-settings-compiler/020-annotation-processor.png[width="1000px"]

[TIP]
====
If using xref:pjdo:ROOT:about.adoc[JDO/DataNucleus], this setting enables the generation of the `Q*` classes for DataNucleus type-safe queries.

It is also required for frameworks such as link:https://projectlombok.org[Lombok].
====




=== Editor Settings

On the *Auto Import* settings page, check the `optimize imports on the fly` and `add unambiguous imports on the fly`

.IntelliJ Auto Import Setting
image::044-other-settings-misc/010-auto-import.png[width="1000px"]


== Plugins

You might want to set up some additional plugins.
You can do this using `File > Settings > Plugins` (or equivalently `File > Other Settings > Configure Plugins`).

Highly recommended are:

* Lombok plugin (bundled with the IDE, and pre-enabled)
+
If you plan to use link:https://projectlombok.org[Project Lombok] to reduce boilerplate.

* link:https://plugins.jetbrains.com/plugin/7179?pr=idea[Maven Helper] plugin

* link:https://plugins.jetbrains.com/plugin/7391-asciidoc[AsciiDoctor] plugin
+
Extremely useful if you are doing any authoring of documents (plugin's git repo is link:https://github.com/asciidoctor/asciidoctor-intellij-plugin[here])

* link:https://plugins.jetbrains.com/plugin/15635-diagrams-net-integration[diagrams.net] plugin
*
Allows diagrams to be authored within the IDE; works well with the AsciiDoctor plugin.




== Running

Let's see how to run both the app and the tests.

We run the application by creating a Run configuration, using `Run > Edit Configurations`.

There is one complication, which is the ORM.
If the app uses xref:pjpa:ROOT:about.adoc[JPA], then dynamic class weaving should be configured.
If the app uses xref:pjdo:ROOT:about.adoc[JDO], then Datanucleus enhancer should be configured.


=== Running the App (JPA)

The screenshot below shows a run configuration for JPA:

image::110-running-the-app/012-run-configuration-jpa.png[width=1000]


With JPA, the classes need to be "weaved" in order to support lazy loading and (more performant) dirty object tracking.
This is typically done dynamically at runtime, using a Java agent.
The xref:docs:starters:simpleapp.adoc[SimpleApp] and xref:docs:starters:helloworld.adoc[HelloWorld] starter apps demonstrate this, bundling the `spring-instrument.jar` file.
To run, use:

[source,bash]
----
-javaagent:lib/spring-instrument.jar
----

as a JVM argument (where the system properties also are located.)


=== Running the App (JDO)

DataNucleus requires that all entities are bytecode enhanced.
When building from the command line using Maven, the `datanucleus:enhance` Maven plugin takes care of this.

We can just have IntelliJ run the enhance as a separate run configuration before the run configuration that runs the app itself.

First, set up the run configuration to do the enhance:

.Run Configuration to enhance the entities
image::110-running-the-app/005-datanucleus-enhance-run-configuration.png[width="700px"]

TIP: Check "work offline" (in Maven Options) to speed this up slightly.

[WARNING]
====
If on Windows you encounter "The command line is too long", then set '-Dfork=false' as a VM option, in Java options:

image::110-running-the-app/006-datanucleus-enhance-run-configuration-fork-false.png[width="400px"]
====

Then, set up the run configuration for the app:

.Run Configuration to run the app
image::110-running-the-app/010-run-configuration.png[width="700px"]

Note how it runs the "enhance" configuration first, specified using "Modify options".

Because we are using Maven to enhance the app, build the app at least once from the Maven command line:

[source,bash]
----
mvn install -DskipTests -T1C
----

You should now be able to run the app using `Run > Run Configuration`.
The same configuration can also be used to debug the app if you so need.


.Dynamic Enhancement ?
[sidebar]
****
Rather than statically enhancing the classes, an alternative -- at least in theory -- is to enhance the classes dynamically, at runtime.

There is an link:https://plugins.jetbrains.com/plugin/11119-datanucleus-runtime-enhancement[IntelliJ plugin] (not tested) that purports to support this, but (at time of writing) is out of date and only supports older versions of IntelliJ.
****


=== Running the Unit Tests

The easiest way to run the unit tests is just to right click on the relevant package in the _Project Window_, and choose run unit tests.
Hopefully your tests will pass (!).

.Running Unit Tests from Project Explorer
image::110-running-the-app/030-running-unit-tests.png[width="500px"]

As a side-effect, this will create a run configuration, very similar to the one we manually created for the main app.

=== Running the Integration Tests

Integration tests can be run in the same way as unit tests.

One approach is to initially run the tests use the right click on the `integtests` module:

.Running Integ Tests from Project Explorer
image::110-running-the-app/045-running-integ-tests.png[width="800px"]

There are also tests in the `webapp-tests` module:

image::110-running-the-app/046-running-integ-tests-webapp-tests.png[width=800]

If the app uses JDO, then the tests might fail because the entities won't have been enhanced.
However, we can then easily update the automatically-created run configuration to run the datanucleus enhancer goal (same as when running the application):

.Integration Tests Run Configuration
image::110-running-the-app/050-running-integration-tests-run-configuration.png[width="700px"]

// CAUTION: Make sure that the `search for tests` radio button is set to `In single module`.
// If this radio button is set to one of the other options then you may obtain class loading issues.


