How to limit BuildShip (gradle eclipse) integrated functionality? - java

Now that I am using gradle for all of my new development, I'm running into issues with BuildShip features I really don't want.
For instance, when I hit the Run hotkey when I have a unit test open in Eclipse, I only want it to run as a JUnit test, alone. But Gradle has inserted its own hooks and option, which means extra clicking or keypresses beyond the one-stroke hotkey I have assigned to Run that I can tell it I want JUnit. (The gradle test option actually runs all tests, which takes minutes.).
Question: Is there a way to remove this hook in gradle without diving into the source code and ripping out functionality myself?
This isn't the only interference (interfering with run last is another), but it's my #1 annoyance about BuildShip.
Essentially, I want this popup to stop happening.

Indeed you cannot change the available launchers prompt but you can change the default hotkeys related to each launcher and directly use the one you prefer.
From Windows > Preferences > General > Editor > Keys you can get the list of available hot-key mappings. Filter the (long) list by typing test as show below:
As you can see you have several mappings for running JUnit tests: Gradle, JUnit runner, Maven.
The default configuration for JUnit runner is Alt+Shift+X,T, not really user friendly I would say.
I changed it to a more concise Alt+U down in the Binding option and applied the changes. Now you can run any JUnit test on its open editor windows without any prompt, simply type Alt+U and the JUnit runner will be triggered automatically for that single unit test.

This is a major usability annoyance in Eclipse+Buildship. I perform the following steps every time Buildship upgrades to get rid of that annoying popup, and also avoid the (for me, useless) Gradle test process when what I really want is for the last test to run while I am not in that particular class. Admittedly, this is invasive, but it works while keeping the "good" parts of Buildship.
Open up the plugins folder and look for the org.eclipse.buildship.ui_*.jar. (I do this on a Mac, which requires showing the contents of the Eclipse.app first.) Open the .jar file in some zip file editor which can modify files within the zip file (I use BetterZip on Mac, I think Winzip and 7Zip probably work too.) Edit the plugin.xml file.
This is for the new Photon 4.8 release of Eclipse. Remove (or comment out) the following two sections:
The <command> element with id="org.eclipse.buildship.ui.shortcut.test.run"
The <extension> element with the comment <!-- "Gradle Test" entry in the "Run as... " context menu --> above it (about 30 lines)
Save the file, which should be noticed by BetterZip/Winzip and let it update the .jar file with the changed content. Finally, eclipse needs to be restarted with the -clean switch so that it does not use a cached copy of the jar file. For example, on Mac:
cd /Applications/eclipse-jee-photon-R-macosx-cocoa-x86_64/Eclipse.app/Contents/MacOS
/.eclipse -clean
Buildship will now no longer bother you with that popup or run the Gradle test within Eclipse, because the UI entry points have been removed. Unfortunately, on the next update of Buildship you need to repeat the process again on the new jar.

Related

Intellij build times are too long. Gradle not helping

I am frustrated by the long build time that IDEA needs before starting my application. I do use DCEVM to enjoy changing code on the fly better than plain hot-swap does, but this doesn't work if I really do need to start my applications multiple times.
IDEA is supposed to be able to have incremental compilation, but I'm not seeing it. I see no options to enable this. Start or starting a debug of the application, takes nearly half a minute. Must it take so long? In theory, IDEA has all the class files already generated, except for the source files that were just edited. IDEA ought to be able to fill in the few blanks, and get the application running almost instantly. What's the hold up, why does it insist it must re-compile every single source file again?
ps. I'm using the Eclipse compiler in IDEA, so that it tolerates some source files not being compilable. I have to do that, because it is one giant tree of java files, where I can not control every one.
Then I saw that perhaps Gradle does have incremental compilation. So I thought to re-create my project, this time with Gradle. I am having a very difficult time figuring out how it works, how it integrates, what tasks are moved from IDEA to Gradle (if any). Even creating a simple skeleton test application with Gradle in IDEA is very frustrating. There are all sorts of fuzzy bits all over the place that leaves you guessing. The tutorials on Jetbrains are almost useless. I can't find one single clear to the point that just explains it in a nutshell how it works. I see some demos that says, click here, and here, and there, but the results on my end aren't the same as what I see outlined.
For instance, Gradle complains that it can't find the junit jar. Ok, so I go into the project settings, and attempt to add the junit jar to the classpath. Under Libraries, I then see an entry to "Gradle: junit:junit:4.11". But there is a second one: "junit-4.11". Why two? Can I delete one? Why is the one so verbal, colon this colon that, etc.
So I add the junit jar files I have to both.
But then in the Gradle Projects window, where I see the hierarchical breakdown of the gradle project setup, verification->test. This is then supposed to run the test class I did manage to create.
FAILURE: Build failed with an exception.
* What went wrong:
Could not resolve all dependencies for configuration ':testCompileClasspath'.
> Could not resolve junit:junit:4.11.
Required by:
xpert_client4:xpert_client4:1.0-SNAPSHOT
> No cached version of junit:junit:4.11 available for offline mode.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
"Could not resolve junit:junit:4.11".
Gradle is extremely frustrating. If all I have to have, is to start a main() in a large project, why would I go through this trouble of using this gradle system that offers things I don't need? Why is it so convoluted, fuzzy, and confusing?
Same goes for an Android project. IDEA can compile and run an Android app without Gradle just fine. Simply avoid anything gradle when setting up, and it just works.
Plus there are all the things that one has to do to speed up the supposedly slow Gradle system. There is the daemon thing. Parallelize, and apparently you can set it in two ways (why). Configure on demand. Globalize. Minimize. minSdkVersion. Offline (oh no, not that Maven thing that pulls down jar files from the internet over and over). jCenter. Profile.... it goes on and on. All those workarounds, hacks, adjustments, tweaks.
Is there anything to be gained by gradle-ifying a working IDEA project? Would I get faster build and startup times if I go through all this trouble? Can I avoid Gradle altogether, and forever (in the hopes that it doesn't somehow becomes mandatory).
I've been coding since the 80s. I've used all sorts of systems. I've build my own build systems. I'm not green here. I also hate having RTFM, if those FMs don't get to the point, and don't explain things well - as if the ones that wrote it, don't really understand it themselves - they know what buttons to press to get it going and that's it.
I find this thing one of the most frustrating things I have seen in a long time. The previous horrible build system I've tried in the past, and have avoided like the plague since, is Maven. The lack of clear thinking with these systems is astounding.
So, aside from these frustrations, what I'm after is: is it worth figuring out Gradle and applying all the workarounds and tweaks, so that I may, once I go through this grief, enjoy faster build and startup times of my application?
Or, would I be better off, avoid Gradle altogether, and instead, do something like place the startup of my application in a loop, so that every time I exit that the application that it re-runs main(). I would then use DCEVM to code on the fly while possible.
Lastly, I forgot to mention. Enabling automatic build in IDEA works really badly. A build seems to always involve re-building every single file, over and over. And setting build to automatic, all it ends up doing is it redoing this in the background over and over. There is nothing that happens in an asynchronous way, where when I finish editing a source file, and start the debug of the application, where IDEA has done any of the building in the background ahead of time, because it redoes the whole thing again after every single tiny little code change. Plus it makes the CPUs spike to near 100% constantly.
IDEA is a great IDE, but the whole compile thing is a total nightmare front to back.
Make sure to disable anti-virus protection in your Gradle caches directory and your IntelliJ project directory. For me, this reduces Java compilation time dramatically, because of all the intermediate files and JARs associated with Java builds. Excluding those same directories from Windows Search indexing can also help.
As of September, 2020, this is the list of default directory locations that should be exluded from virus scanning and Windows search indexing, published here.
Gradle cache: %USERPROFILE%\.gradle
Android Studio projects: %USERPROFILE%\AndroidStudioProjects
Android SDK: %USERPROFILE%\AppData\Local\Android\SDK
Android Studio system files: %USERPROFILE%\.AndroidStudio<version>\system
I published some instructions on my blog for doing this for Windows Defender and Windows Search Indexing, which I'll repost here for completeness:
Windows Defender - How to Exclude a Directory
Open Windows Defender Settings
Click "Virus & threat protection"
Click "Virus & threat protection settings"
Scroll down to "Exclusions" and click "Add or remove exclusions"
Click "Add an exclusion" and select "Folder" from the drop-down menu
Navigate to the directory to be excluded, or paste its path into the "Folder" text-box, and click "Select Folder"
Windows Search Indexing - How to Exclude A Directory
Open Windows Control Panel
Search for "index" and choose "Indexing Options"
Click the "Modify" button
Under the appropriate drive letter, navigate to the folder you want to exclude, and make sure it is unchecked
Double-check your work by verifying the directory shows up in the "Exclude" column of the "Summary of selected locations" table
Even I was facing the same issue and found one option in Intellij IDE, which closely solves my issue, but not fully.
Build Project Automatically and Compile in Parallel
Though it does not solve fully, but I see some performance improvement in build time, whenever I add/upgrade dependency and run the tests.

Trigger Eclipse clean via command line or automatically at a specified time

Is it anyhow possible to force a running Eclipse to clean and rebuild from command line in linux or time triggered?
I have a workspace with hundreds of Maven projects that have to be cleaned an rebuild after a file change automatically. The file change is happening every night triggered by a cronjob which runs svn update followed by a mvn clean and a mvn install at the end. Eclipse itself sees those source changes and rebuilds automatically (native hooks) to keep being up to date. But because of unknown reasons it does not rebuild completely. A lot of errors and warnings remain. Those errors disappear only if I clean the whole Eclipse workspace which then results in an automatic rebuild in Eclipse. This rebuild takes a long time (> 1 hour). I don't want to spend this time every day. So I'm looking for a automatic way to force a complete clean and rebuild of my workspace of a running eclipse over night.
I can't restart eclipse over night.
One idea is to clean Eclipse from outside (but how?) to let it notice the change by itself. Eclipse might then rebuild automatically.
As far as I'm aware, there's no predefined way to trigger this from the outside. So I'm going to propose a strategy which can achieve what you need. This touches on a lot of advanced topics so I'm only going to provide some pointers to get you started, because bringing all the details will be too much for this format. It would probably make an excellent blog article tho. So here we go:
Write a plugin for your Eclipse.
This plugin hast to expose an MXBean with a Clean-and-Rebuild operation. Use the JDK tool jconsole to check the operation's accessibility.
That operation in turn executes the clean and the full rebuild commands. You can use the Eclipse Plug-in Spy to find the appropriate command contributions, and/or scour the Eclipse source code.
Then, you need to build a custom JMX client which invokes that MXBean operation from the outside. This is basically a stripped down version of jconsole's JMX capabilities and can be a simple Java command line app your cron job calls. It needs to connect to your local Eclipse instance and invoke the operation you defined earlier. In order to find the correct instance to connect to, your Eclipse plugin could write the port of the instance's MXBean server to a file your JMX client looks for at startup.
EDIT: In addition to the clean and rebuild commands, you'll want to invoke a full refresh of the workspace beforehand.

How do I lock Run Configuration in Eclipse?

Eclipse Juno SR2 (and previous versions as well) regularly breaks my Run Configurations. It removes some of the program arguments, changes ports, etc.
Is there any way to lock Run Configuration?
In the Run Configuration dialog, go to the Common tab. Select 'Shared file'. There you can save your run configuration to your project, even place it under source control. That way you can be sure it is unchanged.
Have a look at the "Common" tab of the run configuration, where you can save a run configuration as "shared file" directly in your workspace. Then you can make it read-only, and additionally put it under version control like a normal file and restore it in case of problems.
That said, normally Eclipse plugins do not modify existing run configurations once you have manually changed them, so maybe there is another problem.

Purpose of the "Build Automatically" option in eclipse

What is the purpose of Build Automatically option in Eclipse (Project-->Build Automatically)? Mine will always be checked. But when ever I have some java code changes I still have to do a full build. I was told that it should always be checked. I don't see any benefit in doing so. Please somebody explain.
Eclipse has a good answer on their website:
You have two modes of working: auto-build mode and manual build mode. By default, you are in auto-build mode and Eclipse takes care of compiling source files automatically. Builds occur automatically in the background every time you change files in the workspace (for example saving an editor). Auto-build is convenient because it means problems view, binaries, etc. are are up-to-date at all times. The downside is that in large workspaces auto-builds can be time-consuming if you are changing files in projects with lots of downstream dependent projects.
If auto-build is taking too long and is interfering with ongoing development, it can be turned off. Once in manual build mode, the user is in complete control over when builds occur and what gets built. Project > Build All (Ctrl+B) can be invoked at any time to trigger what auto-build was doing automatically. This allows you to build up a larger set of changes before invoking a build (Eclipse remembers which files have changed so that it does not have to do more work than required when you do ask for a build.
Note that when they say "auto-build mode" they mean if you have checked "Build Automatically", when they say "manual build mode" they mean you do not have "Build Automatically" checked.
Yes, you still have to do a build - but it's done automatically when you save (not an external build like an Ant build, but the "internal" build). If you didn't want to build on save, you'd uncheck the box. Having it build automatically makes some people nervous, I believe.
NOTE
For C/C++ users it's told (from help.eclipse.org):
By default, the Eclipse workbench is configured to build projects automatically. However, for C/C++ development you should disable this option, otherwise your entire project will be rebuilt whenever, for example, you save a change to your makefile or source files. Click Project > Build Automatically and ensure there is no checkmark beside the Build Automatically menu item.
Project - Disable Autobuild option does not always mean autobuild is off. For example "Makegood" test automation plugin will trigger autobuild when Preferences - Run/Debug - launching - (General opt) Build before launch is ON. So turn it off if manual build needed.
One thing that people didn't mention here (and it took a while for me to figure this out too) is that eclipse build (either automatic or manual) would basically follow what you have outlined in the project's "Java Build Path" source tab. So when a file is covered in that build source tab, when you change the file, it gets copied/compiled to the output folder that was specified for that directory/file.
One more difference is:
Most of the time while working on JSPs it helps me when checking "Build Automatically". It automatically picks up the changes in JSPs.
But if you make changes in your java classes/XMLs you need a manual build.
Since I'm using resin server which is run outside eclipse via command prompt, i prefer checking the option.
When i have my server setup in eclipse, i turn it off and use Publish on server.
This is the way i use and the answer is based on my experience.
If Build Automatically is checked, the IDE will automatically compile your Java code whenever you modify and save a file. This does not mean it will completely build and package your entire solution as if you were going to deploy it such as if you are working in a Web project on a WAR module. It basically really just compiles your code.

Eclipse not synchronized with file system changes made by ant's build.xml

We have a pretty big project. We use ant for setting the environment. One of the things that happens during the ant script is that a jar is copied to the lib folder of a project. Then, we use ant tasks: eclipse.refreshLocal and eclipse.incrementalBuild so that the jar now copied will resolve compilation problems in the project that refer to it.
Unfortunately, the projects seem unsynchronized with the filesystem. Project > properties > build path shows that the jar is present (probably information that is refresh while looking at the propertiesw) but the incrementalBuild didn't do what we expected it to do.
Also, sometimes a project that depends on this jar and we refreshed and built it (through ant) has a single compilation error: "The project cannot be resolved until build path errors are resolved". In other times, the are many compilation errors indicating the project hasn't noticed the new jar.
When I build it through eclipse, it is ok.
I was worried that maybe there are circular dependencies between the projects, but it appears the are no such dependencies (Build properties: the circular dependencies option is set to "Error", and the are no errors of this form in the projects).
Anybody is fimiliar with the problem?
What is the proper way to deal with this problem?
Thank you for your help.
If you right click on the build.xml and select Run as → Ant Build... you'll see a tab called Refresh. Just check the option Refresh resources upon completion.
(I use this myself when generating code in an ANT xslt target and it works like a charm.)
You may also want to check Refresh automatically under Window → Preferences → Workspace
Try Cleaning the entire workspace and refresh :)
One solution which might work for you is to modify the Eclipse launch config for the Ant build (Run -> External Tools -> External Tools Config), and explicitly configure it to refresh the workspace (or parts of it) when the Ant build finished. This removes the need to perform the refresh from within the Ant script itself, and it always triggers the correct build reaction when the script completes.
Eclipse does not generally like it very much if you change files in its workspace from outside. There is an option in the Eclipse Preferences to automatically sync with the filesystem, but that can be very intense with regards to IO.
And it will probably still not solve all your problems, esp. when you change library jars.
Even considering skaffman's suggestion with the Refresh on build completion, I am not sure this would really improve your situation, but give it a try.
From my experience, realistically I would have yet to see a solution in a big setup that really works and makes life easier instead of just creating a different set of problems.

Categories