I'm learning how to use gradle to build my java applications. Currently I'm using eclipse with buildship plugin. I have it building my JARs and WARs, and also have gradle running my JUnit and Selenium tests. I like that it pulls in the dependencies I need as I need them during development.
It seems like it would make sense if my build.gradle files define my dependencies to build and run my application in dev then I should be able to use them for deployment. Otherwise I have to retrieve all my dependencies by some other means and deploy to my production environment, and managing 2 different methods of retrieving and deploying dependencies seems to be a risk for problems.
Can I use gradle or at least my build.gradle files in some way for my deployment?
Take a look at the gradle distribution plugin. This plugin adds tasks to create an "install folder" or an archive file (zip or tar) containing all the dependencies you'll need to execute/deploy your application.
Gradle application plugin also generates shell/bat scripts to invoke your application.
Related
We use Eclipse to launch and debug our Java GWT project. We have a couple of eclipse launch configuration files with many classpath entries needed for running the project.
Previously we used ant to build our project and had all our dependencies present on our local storage, with all classpaths pointing to libraries explicitly for project as well as launch configuration classpaths.
Once we migrated over to Gradle 6.6 and used public repositories to download our dependencies, almost everything worked smoothly - all our project classpaths were generated correctly by the gradle build. However, our eclipse launch configurations still contain the old hardcoded classpaths and I'm unable to find a way to generate these launch configurations using those gradle configured classpaths. As a result we've had to maintain the dependencies on our local filesystem so that the configurations have access to them in order to debug and run our code.
Is there a way Gradle can be used to generate these launch configurations so that we can get rid of the libraries on our filesystem and rely on whatever it pulls from the repositories during a build?
Any suggestions or workarounds will be appreciated.
It you're using Eclipse's built-in Gradle tooling (aka, Buildship) and let Eclipse generate your launch configuration, it will automatically be in sync with the project's build path, which is automatically kept in sync with the dependencies declared in your Gradle build file.
Here is an example Gradle project I just created, where I added some dependencies and the launch configuration "just works." The project is named "lib," notice under Classpath Entries is "Project Dependencies"; that's where Eclipse's Gradle tooling maintains and syncs with what's in the build.gradle file.
Here's what the project's Build Path looks like if I inspect it:
Whenever you add a dependency to build.gradle, it will automatically be included there; the launch configuration(s) then reference the project dependencies so the launches are also always in sync.
You might need to delete your existing launch configurations and let Eclipse generate new ones to get this.
Currently, my built structure for a plugin in is a bit messy: I'm using the normal IDEA project file to build the plugin locally. When I push it to the repo and travis-ci is building it, it uses the maven pom.xml because for travis to work, it always has to download the complete IDEA sources.
Although this works, this has several drawbacks:
I need to keep two built mechanisms up to date. This is
When a new IDEA version is out (every few weeks), I need to change the SDK in maven and in my IDEA settings
When I add a new library, change resources, etc. I need to do this for two the two settings as well
I ran into problems when I kept the IDEA Maven plugin turned on because it saw the pom.xml and interfered with my local built. Turning it off means, I cannot download libraries with Maven which has the feature of tracking dependencies.
I saw that Gradle has an 'idea' plugin and after googling, I got the impression that Gradle is the preferred choice these days. I have seen Best way to add Gradle support to IntelliJ IDEA and I'm sure I can use the answers there to turn my pom.xml into a valid build.gradle.
However, maybe someone else has already done this or can provide a better approach. What I'm looking for is a unified way to build my plugin locally and on Travis-CI.
Some Details
For compiling an IDEA plugin, you need its SDK which you can access through an installation of IDEA or a download of the complete package. Locally, I'm using my installation for the SDK. With Travis, my maven built has the rule to download the tar.gz and extract it.
It turns out that in particular for building an IntelliJ plugin, Gradle seems to have many advantages. This is mainly due to the great IntelliJ plugin for Gradle which makes compiling plugins so much easier. With Gradle, I could turn my >220 lines of Maven build into a few lines of easily readable Gradle code. The main advantages are that
It takes care of downloading and using the correct IDEA SDK while you only have to specify the IDEA version.
It can publish your plugin to your Jetbrains repository and make it instantly available to all users
It fixes items in your plugin.xml, e.g. you can use one central version number in gradle.build and it will keep plugin.xml up-to-date or it can include change-notes
It seamlessly integrates with Travis-CI
How to use Gradle with an existing IDEA plugin
Do it manually. It's much easier.
Create an empty build.gradle file
Look at an example and read through the README (there are many build.gradle of projects at the end) to see what each intellij property does.
Adapt it to your plugin by
Setting the intellij.version you want to build against
Setting your intellij.pluginName
Define where your sources and resources are
Define your plugin version
Define a Gradle wrapper that enables people (and Travis) to build your plugin without having Gradle
Create the gradle wrapper scripts with gradle wrapper
Test and fix your build process locally with ./gradlew assemble
If everything works well, you can push build.gradle, gradlew, gradlew.bat and the gradle-folder to your repo.
Building with Travis-CI
For Travis you want to use the gradlew script for building. To do so, you need to make it executable in the travis run. An example can be found here.
Is it true that one of the real benefits of Maven is that its projects structure is clearly defined and therefore it can be opened in any IDE that supports Maven?
We develop in a team consisting of 5 people and we use three different IDEs (IntelliJ, Eclipse, Netbeans). I know that I cannot open an Ant project of Eclipse in Netbeans but with Maven this is possible.
Is this really reason enough to use Maven?
Maven and Ant are two different things.
Ant is a build tool while Maven accumulates the functionality of:
resolving dependencies (you only specify the dependencies, and Maven cares about downloading them in the correct version from the default repositories on the i-net, or the ones you specified explicitly)
a build tool (incorporating Ant),
creating distribution artifacts (containing not only the jar/war/etc. file of the project but also dependencies, resources, documentation),
runtime environment (e.g. starting Jetty and deploying your artifact)
unit testing
integration testing
deployment (including signing, incrementing the version, deploying the artifacts etc.)
and more (look out for plugins on i-net)
Maven uses lifecycles to achieve this. You can trigger certain functionality at certain points in the lifecycle. For example unit tests should be run right after compiling while integration tests (e.g. selenium tests) require more setup, maybe initializing a web server and deploying the WAR file.
A bit of background about my knowledge level: I'm currently trying to learn how to build a project with gradle. So far I don't have much experience with build tools (almost none). I do understand the general idea and have seen ant and maven files before but never written them myself. Until now I just used other peoples build scripts or configured my builds using Eclipse. So I might be on a completely wrong track here, if so please point me in the correct direction.
Also, I sadly don't have much experience building jars by hand.
I have an Eclipse project which I want to compile into a jar. Required library jars are on my local file system. I managed to make gradle use these via
dependencies {
compile fileTree(dir:'lib', include:'*.jar')
}
in addition I have my source files in src/main/java and just use apply plugin: 'java' in the build.gradle file. Trying to build the project with gradle build seems to do the right thing, as far as I can tell.
However, the library is supposed to be used in a web project running on a tomcat and makes use of some libraries that are supplied by tomcat, as far as I understand. E.g. I'm using javax.servlet.http.HttpServletRequest.
The project works fine in Eclipse, but there I have the tomcat library added to my Eclipse build path. When I check in Eclipse I can see that javax.servlet.http.HttpServletRequest is part of the servlet-api.jar which is part of the Tomcat library.
Now, when I build the project I get build errors because the java compiler cannot find the class because I didn't specify the servlet-api.jar in the dependencies. I guess I could download it somehow (or learn how to specify it as an external dependency to make gradle download it from some repository) but I am not sure whether that would be correct.
Is there a way to tell gradle to use the same library that Eclipse uses? Or some other general way to tell it about all the tomcat jars, the same way I can simply add the complete Tomcat library in Eclipse?
Or do I actually need another copy of these jars somehow and have to specify each one individually?
Also, do I need to add these library jars to my build-result library jar? As far as I know I need to add any jar I depend on to the resulting jar as well. But then again, I have read somewhere that some libraries are supplied by tomcat itself so they would have to be part of any war deployed on it.
I'm afraid, I'm confused by the combination of how to build a jar-file to be used in a war-file to be deployed on a tomcat using gradle and I don't know from which of these parts my problems originate. I hope someone reading this can help me untangle my thoughts and point me in the right direction or at least tell me how to add the jars included in the Tomcat library to my gradle dependencies.
With Gradle, whenever you add files or directories as dependencies, they are not treated as full-fledged artifacts (with group, name and version), but rather as simple files containing classes. It means that Gradle will not perform any conflicts resolutions on them, or pull transitive dependencies.
For you, just to get started, I recommend just to add tomcat dependency. Make sure it is the same version as the one in Eclipse.
apply plugin: 'war'
repositories {
mavenCentral()
}
dependencies {
providedCompile 'org.apache.tomcat:tomcat-catalina:7.0.47'
}
Also, look into Eclipse Integration Gradle project as a long-term solution.
I have a standalone application which I have deployed using the Maven release plugin.
I now need to run it on the remote server...
Would you recommend using the mvn exec plugin?
Otherwise whats the best way of running the app (i.e. working out the correct classpath etc).
Thxs
You can use the Maven Assembly Plugin with jar-with-dependencies descriptor (it's one of default descriptors). It should include all dependencies, allowing you to easily run the jar on the server.
Either the exec plugin, or use the dependencies plugin (or any of the jarjar-/onejar-type utilities) to create an all-in-one jar and just distribute that.