I am on Grails 1.3.5 and IntelliJ 9.0.4 on a Mac with the latest JDK
I have the simplest of Grails projects: a helloworld that simply renders a string directly from a controller. I created it through the New Project wizard in IntelliJ. That went fine and IntelliJ picks up the correct grails SDK.
The problem is that IntelliJ makes me restart the app to see any changes I make to my code, (e.g. changing the "hello world" string.
If I edit the same controller with a text editor (eg TextMate) and run the app from the command line with grails run-app I do get hot code replacement, which is obviously what I want...
Anyone got a clue?
Some points:
I strongly recommend using the latest IntelliJ X EAP (http://confluence.jetbrains.net/display/IDEADEV/IDEA+X+EAP) since Grails support has been improved a lot since 9.0.x
If your IntelliJ config files got messed up, you can easily recreate them with 'grails integrate-with --intellij'. N.B. this recreates the config files in and old format and IntelliJ suggest to upgrade them - follow this procedure
Make sure your run configuration has uses at least the same memory settings than Grails uses when run from the command line, I'm fine with setting the 'VM parameters' field to '-XX:MaxPermSize=256m -Xmx1G'
If build problems occur (in rare cases the IntelliJ's internal compiler is more strict than plain Groovy), disable the 'Make' checkbox in the run config dialog.
If the problem persists, paste a screenshot of the run configuration you're using.
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.
I have just installed Netbeans 11.1 and when I save one of my Java files, Netbeans does not start a gradle build automatically. This used to work in Netbeans 8.2.
I have installed nb-javac and have also tried the newest Beta version to no avail.
Is this a known bug or do I need to reconfigure something when going from NB 8.2 to 11.1?
(This is only an explanation rather than a solution to your problem.)
First, Compile on Save is an option which is set or unset at the individual project level, rather than at the global level. So for a NetBeans Gradle project, select Properties > Build > Compile to view the setting for the Compile on Save checkbox. For that checkbox, note that:
It is unchecked by default, so there will not be an automatic Gradle build when you save a project file.
It is disabled, so you cannot trigger a build whenever you save a project file.
The problem persists in the latest beta of NetBeans 11.2.
I don't see a bug report for this issue, so perhaps you can raise one? Click the Log In button to sign up first if necessary.
That said, there is a related issue which may explain why the check box cannot be enabled. See closed bug NETBEANS-680 Erroneous Gradle Compile-on-Save activity which relates to Gradle projects using version 9.0 of NetBeans. Apparently there were spurious and unwanted compile-on-save runs being triggered even though Compile on Save was unchecked. Perhaps the feature has been deliberately disabled for Gradle projects because of that issue, though that is just speculation on my part.
Also see the GitHub page for the Gradle plugin. Comments from the NetBeans team for NETBEANS-680 suggest that the problem was with the plugin rather than NetBeans. That said, if NetBeans is offering functionality that cannot be enabled (i.e Compile on Save), it is definitely a NetBeans issue regardless of the underlying cause.
Finally, note that you can configure the Gradle plugin using Tools > Options > Java > Gradle, but I dodn't see any options there that would help with this issue.
We have inherited a SpringBoot project written in Kotlin. Using Intellij, I would expect to be able to go to the Application main method and click the green arrow to start the project. I would also expect to be able to run the project in debug mode and set breakpoints, this only works with tests.
When I try and run the project I get a exception FileNotFound which has yielded me no answers. Every file appears to be accounted for and there is clearly nothing missing.
This is a multi-module gradle project with many unique configurations and I suspect one is causing an issue. I am having trouble determining which configuration is causing the issue because the project doesn't even seem to get to the point of standing up Spring (no banner).
I have tried many different combinations of bash scripts, environment variables, and gradle tasks and the project does not seem to run at all. Is there any way I can use Intellij to debug the sequence of configurations and gradle tasks?
So, I am answering my own question because searches lead me nowhere and this was a surprisingly difficult problem to debug. It turns out I was taking the wrong approaches and asking the wrong questions. I took a lot of time to study up on Spring configurations and Gradle tasks to realize none of our stuff was wrong. The Kotlin compiler was failing at the very beginning.
What had happened was one developer naively cd'ed into the Application's module and ran an echo statement that piped gradle output to a file called out with no extensions.
Kotlin would find this file and then proceed to not compile anything starting at the Application main. When we ran the app from terminal the app would recompile itself from the very beginning with no problems. But the automatically generated Intellij config simply ran the app with the bad file every time.
The troubling part was that our .gitignore file was configured to ignore all of the kotlin /out/ directories, but not files like /out so this troublesome file was committed to the repository for quite a while.
Surprisingly, deleting this out file fixed most of the issues our project had with Intellij.
Another note:
Our script was also set to source certain variables from other scripts, which meant we either had to carry them over to the runtime configs. We could also run Intelli from the same terminal we had already sourced the script in (using Tools> Create command line launcher). Once I had that sorted the project ran and debugged perfectly.
I have observed an inconsistent way properties are being read in Eclipse. I have a very simple Springboot web project with typical property files. Here is my project layout:
Notice the two property files: testapplication.properties and application.properties. They are identical at this point, the intention is to use them for test and non test environments.
When I try to run this application in Eclipse, I am getting an error about missing expected property values, for example:
Could not resolve placeholder 'min.thread.count' in value "${min.thread.count}"
When I run the same setup using gradle's bootRun task, it works fine.
When I run the same setup in InteliJ it works fine.
If I rename the testapplication.properties to application.properties the application runs fine in Eclipse. As such it is using property form test folder.
In addition, I am pretty sure when I started Eclipse this morning I was able to run the application with a proper application.properties and testapplication.properties files. I was working on a unit test and renamed the testapplication.properties to application.properties, did some work, then renamed it back to testapplication.properties the application refused to start. I have attempted to replicate it: shut down eclipse with two different property files (application and testapplication), start it again and run application. However, at this moment I have the same issue (complaining about missing property value).
As you can see this i weird behaviour. As it stands I find that I cannot use Eclipse as I am not sure what it will do. I've switch to community edition of InteliJ as it seems to be working correctly. But as a long time fan of Eclipse I am heartbroken :)
Does anyone have any clue what could be causing this?
EDIT:
I have checkin in my test project here:
https://github.com/twolak2003/CamelSpringBootEureka.git in branch PropertyFileIssue. Simply clone, switch to PropertyFileIssue branch, import to eclipse as gradle project.
It is a simple vanilla spring cloud boot project running a eureka server and eureka client. For the purpose of this issue we'll just concentrate on eureka-service.
I am using latest Eclipse Oxygen. I did notice the same issue in Eclise Neon. I switched to Oxygen hoping the issue will go away. Only plugin is the Spring IDE. Using Java 8 to run this.
Test 1: Start the EurekaService/src/main/hello.java as Java application.
It starts fine and will read the src/main/resources/application.property file.
Test 2: Rename the EurekaService/src/main/test/resources/restapplication.properties to EurekaService/src/main/test/resources/application.properties. Start the EurekaService application again.
Findings: It starts fine as well BUT it uses property file in the /src/test/resources. This to me is issue as well, it should not be using /test/ for running the application.
Test 3: Now rename the /src/test/resources/application.properties to /src/test/resources/testapplication.properties again. (this is repeat of test1). Once again run EurekaService/src/main/hello as java application.
Finding Despite this being a repeat of test1 the test failed due to "Could not resolve placeholder 'tomek.prop' in value "${tomek.prop}"".
Am I doing something really stupid or is there an issue?
For now with heavy heart I am switching to InteliJ to keep my project going. The behaviour of Eclipse is just too unpredictable for me to stomach for now :(
So far I don't have a correct answer for this other than stop using Eclipse :). But there is workaround.
DO NOT use more than one application.property file.
If you need test properties to override actual properties then name your file as anything else but "application.property". Otherwise you'll get unpredictable behaviour and your Eclipse runtime get's confused.
We are having a strange issue with our Jenkins plugin. In the development environment (running using mvn), the plugin works perfectly fine. But when we install the plugin (using marketplace or hpi file) to seemingly any version of Jenkins, it is totally broken. Our post-build action (publisher) registers but our configuration form is completely blank. It only shows the delete button to remove the action. What could be different about running from maven (hpi:run) vs installing from the marketplace or hpi file?
I finally figured it out. The capitalization of the resources folder that corresponds to the publisher must match the capitalization of the publisher class name. I think this would probably only be an issue on windows. Also its strange that it works totally fine in the dev environment.