I've seen a few articles describing how to debug Scala applications, but nevertheless I want to ask it again due to the reason that all those articles are outdated and all things change very quickly in Scala world.
I use IntelliJ Idea 12 + sbt (not a plugin, a plugin doesn't work for some reason).
So how do I do that nowadays?
IMO, you are best off keeping SBT and Intellij separate, as they are two different concerns. One is for building, and the other is for developing.
Here are the steps that I typically go through to get a solid Scala/Intellij development environment up and running for a new Scala project.
Step 1: Install Scala Intellij Plugin
Step 2: Create a simple sbt project - details here
Step 3: Add the fantastic sbt-idea plugin to your sbt config
Step 4: sbt gen-idea
Step 5: Open project in Intellij 12
Enjoy debugging, syntax highlighting, code assist and all of the other nice IJ features.
On the sbt side, I typically keep a terminal open, with sbt running so that I can rapidly test things outside the context of Intellij.
HTH
Related
Questions
My questions are:
(Q) When running an app in the IntelliJ debugger, how does IntelliJ decide which bytecode to use ?
(Q) Does IntelliJ use whatever maven build plugin is being used or simulate it?
(Q) If multiple conflicting versions of code are being used (see mvn dependency:tree -Dverbose), how does IntelliJ decide which version of the code to use?
(Q) Where is the JAR file that IntelliJ creates so I could inspect it to see what versions of classes were used?
(Q) Is the process of selecting classes to use any different when running vs debugging?
Note: This question is being directed to IntelliJ's support staff as well as the SO community.
Background
I have an app that has been very problematic with IntelliJ with regards to picking the desired classes when running the application.
The app is a Java Executable Jar that has been packaged with the maven-assembly-plugin. It is not a SpringBoot application.
The problem stems from IntelliJ picking different class files than the maven-assembly-plugin which copies all of these classes (from all of the dependent jar files) into a single jar file. Naturally, only one version of a class can exist in the jar app (I believe the first class copied wins and the others are ignored).
IntelliJ (AFAIK) has no way of knowing what version of what class will be put into the JAR without knowing how the maven-assembly-plugin is implemented; So I'm looking for this answer.
Understanding the Question
To explain, see the example I created to understand how the maven-shade-plugin works. See Is there a sample project in github that shows how to use the maven-shade-plugin?. It's not a perfect fit for my problem/question, but it is in the public domain and it's close enough.
I'll frame my question based on the helloworld example. The helloworld.pom depends directly on loglib:2.0.0 so I would expect IntelliJ to select and use that version when compiling and running the application.
The problem (code changes not being picked up)
The problem I ran into was when I changed the helloworld/pom.xml file to depend on loglib:2.1.0-SNAPSHOT and IntelliJ did not pick up the code changes and used a previous version of the dependency even though the source code was loaded inside of IntelliJ and the loglib/pom.xml file was changed to be version 2.1.0-SNAPSHOT.
The application is run by specifying the main class of the application com.steranka.play.HelloWorldApp. The Run/Debug configuration is:
NOTE: I've done this exact thing many/many times and it's always worked, so I was puzzled. I also tried to reproduce the problem with a sample example and could not reproduce it. IntelliJ worked flawlessly picking up changes as it has always done in the past.
Trying to fix the problem (bytecode not matching source code)
I went through the list of things I've done in the past but after they were all completed, the problem remained. The list of steps I followed included:
(1) Rebuilt the project (which included helloworld and loglib packages). Rebuild was done inside of IntelliJ. Nope.
(2) Verify that the correct maven dependency loglib:2.1.0-SNAPSHOT was being used in helloworld module, and that it shows up in the Maven Tools dependency list.
(3) Clicked Reload all Maven Projects - run from Maven Tool.
After IntelliJ restart, I made a change to a log.info() statement in the loglib:2.1.0-SNAPSHOT module ran my program and my changes to the log statement did not appear, only the previous version of the log message appeared.
This is the crux of the problem, and reason for my question. Where is IntelliJ getting the bytecode that it is running? Is it from loglib/target/classes/* directory (this is my belief), or from maven .m2/repository/ ... / loglib:2.0.0-SNAPSHOT.
(3) I put a breakpoint on the log statement (that I changed) and ran the app in Debug mode and IntelliJ stopped on the log statement when I stepped over the statement the wrong log message was printed. This is when I knew the bytecode IntelliJ was executing did not match the source code.
Detailed steps that reproduced the problem
To be clear I'll give timestamp versions because I don't know exactly what POM versions were being used:
T1: Starting with line that says: log.info("orig message");
T2: I changed the message to log.info("orig message - change1");
T3: IntelliJ did not pick up my change and log/console shows orig message
T4: I added some lines to the source code (multiple log statements)
log.info("this is strange")
log.info("why isn't this working")
T5: I put a breakpoint on the line why isn't this working and the breakpoint symbol appeared
T6: However, when I ran the program and IntelliJ stopped at the first breakpoint (orig message - change1) and when it stopped the 2nd breakpoint symbol was greyed out (indicating that the debugger could not stop on that line).
T7: I stepped and IntelliJ was obviously running different code because the original message appeared instead of the changed message.
More Questions
(Q) When the IntelliJ debugger shows code that doesn't match what is being actually executed, how can I track down what code is actually being used? The answer to my previous questions should answer this.
The observable things I know to look at are:
The Project Settings modules.
The maven tool modules list and the dependencies.
The External Libraries list in the Project Tool.
The target/.jar and target/.classes files.
Settings - java compiler used, maven used,
Common Reasons for this problem (bytecode not matching source code in debugger)
Reason 1: The most common reason for the above problem (in my past) has been making a code change in some module (say loglib when the loglib/pom.xml is at version 2.1.0-SNAPSHOT) and forgetting to update helloworld/pom.xml to refer to the -SNAPSHOT version. In my case I performed this check.
Reason 2: Years ago debuggers did not automatically compile code before the code was run, and this let to the problem whereby the bytecode being used matched the last time the file was compiled. The fix was/is simple, recompile the code and update the *.class file contains your code changes and the debugger code matches the bytecode that is being executed.
How to Reproduce the problem
The maven-shade-example (referred to above) can be used to reproduce the problem where the code shown in the debugger is not used at runtime.
git clone git#github.com:steranka/maven-shade-example.git
cd maven-shade-example
git checkout feature/fixing-problem-another-way
mvn clean install
java -jar helloworld\target\helloworld-1.0.0.jar
The output is:
Hello World!
What's up, Sam
Hello, Sam
Goodbye, Sam
But if you try to open this project inside IntelliJ and build and run it, you'll get an error. To run this, I right clicked on the hello word application and selected Run HelloWorldApp.main() (or Debug).
Hello World!
What's up, Sam
Exception in thread "main" java.lang.NoSuchMethodError: 'java.lang.String com.steranka.play.LogIt.sayHello(java.lang.String)'
at com.steranka.play.GoodFeature.sayGoodbye(GoodFeature.java:6)
at com.steranka.play.HelloWorldApp.main(HelloWorldApp.java:15)
What makes this un-nerving is the debugger jumps to the correct code if you click on the method, it just doesn't use that method at runtime.
The runtime configuration inside IntelliJ is:
#CrazyCoder points out that IntelliJ will run the JAR file created using mvn clean install in the helloworld\target\helloworld-1.0.0.jar if you create a run configuration that says to use Java.
When I created a run configuration to use the Jar file, then IntelliJ's debugger properly executed the application and stepped into the correct files. That configuration looks like this:
When I tried this solution on the actual code causing problems, it also worked. Strangely enough (to me) after switching to the JAR configuration and successfully running, I switched back to my Main class configuration and it also worked! So toggling between the two configurations might work for others as it did for me.
#CrazyCoder also points out that there is an outstanding bug/feature request with IntelliJ that asks for better support of the maven-shade-plugin. See https://youtrack.jetbrains.com/issue/IDEA-266746
#Thorbjørn Ravn Andersen states that IntelliJ emulates Maven so in general the behavior between building and running inside IntelliJ should match what happens with Maven.
While trying to build https://github.com/mozilla/rhino, I'm getting Unable to find method on org.codehaus.groovy.runtime.StringGroovyMethods.
so the build fails, and I'm unable to test Rhino built from source code, which is the goal.
Steps Taken
From the opening screen in IntelliJ, I check out the project:
I get this error Unable to find method ''java.lang.String org.codehaus.groovy.runtime.StringGroovyMethods.capitalize(java.lang.String)'' right away, which I have not been able to fix:
There are two suggestions in the above Re-download dependencies and sync project and Stop Gradle build processes. I have tried both with no improvement.
When I look at the build.gradle file, I see another suggestion ...configure Gradle wrapper to use distribution with sources.... This also does not get past the missing Groovy method problem.
I have looked on S.O. for similar issues and tried various things under File > Settings > Build, Execution, Deployment, but I realized I'm over my head since, conceptually, I'm not sure what I need and where that would go in the settings.
The command line items from the readme work as expected, but going back to File > Build still fails (added after tim_yates comment).
What changes are required to the IDE or to the build definitions to allow Mozilla Rhino to build properly?
I installed the latest (2022.1) version of IntelliJ IDEA Community Edition. During the install, it asked if you wanted this IDE to be associated with Groovy file types, and I answered in the affirmative.
On this new install, the Unable to find method on org.codehaus.groovy.runtime.StringGroovyMethodserror did not appear, so the problem was solved by upgrading the IDE (and also that required updating GIT).
I need to build a javafx aplication to a .exe file, to be used in 3 differents enviroments.
Now, before I build the application to each different enviroment I am changing every variable manualy, like urls, versions and tokens. I know that is a matter of time until I upload the wrong version to the wrong enviroment, so I really need a more automatic process to manage each version.
I read something about maven build profiles but i do not find a way to integrate this in the building of the exe file
This javaFx app is using maven and java10
To build the java code to an exe, I'm using Intellij
Thank you in advance
The big problem is that java 10 is end of lifetime (EOL), so you should already work with java 11, this however is a little more complicated since JavaFx/OpenJfx is now separated. (see https://openjfx.io/)
Anyway to solve your complex needs you should think about a CI platform like as example gitlab CI.
This platforms (with the help of Docker Images) give you the tools you need to properly build and configure complex javaFX build targets and configurations.
But you have to build the .exe file on your own with tools like exe4j if you choose this path.
Side Tips:
In my experience is a lot more easy to build java 11 applications
with gradle instend of just maven since you gain a lot more
flexiblity to solve complex problems
If you stay on java 10 it would be much easier since Java11 + Openjfx
11 required OS dependend builds. (but as I sayed it is EOL)
Currently, I'm making web-apps using php [backend] project and AngularJS [frontend] project. To make above two projects simultaneously, I need to run 2 programs (Webstorm and IntelliJ).
But, I want to run two projects just using IntelliJ. I already tried before, but the IntelliJ performance was so bad and I don't know why. (I gave IntelliJ 4G of RAM and other options to run it smoothly, but it also returns slow performance.)
I installed Angularjs support, PHP/Laravel support, and Java/Spring support, and other plugins on IntelliJ.
I assume that this made IntelliJ slow, but I need to use above plugins to keep developing.
I'm using webstorm and Intellij for both front and back-end programming in fast speed.
In this case, do you have any idea to improve performance of IntelliJ when Running 2 programs simultaneously on intelliJ?
The reasons why I'm trying to run just IntelliJ are I just have only IntelliJ license and switching between front-end and back-end program is easier than 2 program. (It can be done just by command + ` to switch both project, but I need to command tab many times to switch between project. It makes me hesitate.)
If you have idea or have any manual which I didn't find before, please let me know.
I use IntelliJ IDEA version 13 on MacOS. I have a maven project, the project is stored in Git. Everything worked well.
Yesterday my Macbook crashed, then I reinstalled MacOS as well as IntelliJ IDEA. After that I checked out my project from Git and open the project in IDEA again. But now In Maven Project's Lifecycle, test is disabled, there a dash across test. I can still package my project, but "Tests are skipped".
Since my project code has no any change, I'm guessing I might miss configured something in IntelliJ IDEA. Any idea?
There's a skip test toggle in Maven Projects tool window.
To enable the maven Test, these are two steps need to complete
Step-1: Go to the settings tab, then go to Build, Execution, Deployment
Step-2: Then select the testing, and uncheck the Enable test runs.......