This sounds dumb but is there anyway for me to specify dependencies for my Java project like how I would in a package.json file so that someone else who was to download the project code from my GitHub repo, would be able to run it without any errors or missing libraries?
I have never tried using external Java libraries before, such as apache commons. The most I ever used was JavaFX but on a personal project level. My main concern is that if I were to push my code up to the repo and have someone else clone it. It might not run properly as the imported libraries are not downloaded.
Is there something similar to package.json dependencies where the person who runs the code would automatically download all dependency libraries and have it run on their system?
You can use Maven or Gradle for this purpose. Maven has pom.xml where you can specify all your dependencies. Similarly gradle has build.gradle which does the same job.
Related
I am creating a java project in IntelliJ (without maven or grandle). The project uses an external library, whose .jar file I’ve put into a /lib directory. After that I had to select at the /lib folder “add as library” to use it.
Now I want to push the project to GitHub, so that some people (who are using IntelliJ as well, but in different versions) can use the project.
Now my question:
Is there a way, that they do not have to do the step “add as a library” themselves?
My first idea was to push also some parts of the .idea folder to GitHub, but I am not sure which ones to push and if that could actually work (especially with different versions of IntelliJ).
Do you have any idea how to solve this issue?
If you are using only IntelliJ for building the project, then yes, you should push the .iml files from the .idea folder (or where they happen to be), since they contain the dependencies configured in IntelliJ.
Note, that projects with multiple contributors typically use a build tool like Maven or Gradle.
This is a special build requirement, which I would use Gradle for. With Gradle you can look up a given folder, like /lib and use all .jar files as dependency.
See Gradle example about exactly what you want.
IntelliJ is handy when you do something simple mostly for learning, but if you want to be a professional one day I highly suggest looking into Gradle. It has a learning curve for sure, but you can achieve such simple tasks like this in your question relatively simply. And as you seem to know, pushing .idea to the repository is really not the nicest thing one can do :)
Just a small additional note: Gradle solves the "different version" problem by including a "Gradle wrapper" inside the repository, so everyone cloning the repository will have the same copy of Gradle as well, so the same build process is guaranteed for all contributors.
Also, when I started programming I downloaded the dependencies and used them as jars. But if you learn at least Maven, and your dependency is uploaded to a repository like Maven Central, you can just paste a line of code into your pom.xml (Maven) or build.gradle (Gradle) and you are good to go :)
I am coming from a C# background. I am used to NuGet and Visual Studio project references so the Java ecosystem has confused me quite a bit.
I have a gradle library project. I want to import org.apache.commons.codec.binary.Base64;
However I keep getting cannot resolve errors.
I am using VSCode as my IDE and I would like to include the codec dependancy. How would I achieve this in VSCode/gradle.
I have downloaded the commons-codec-1.14.jar file, but don't know where to put it in the project.
Gradle is a tool that, among other things, manages your dependencies. This means that, you do not need to manually download and add dependencies to your project. Gradle solves this for you.
See the official documenation on how to handle dependencies with Gradle.
You probably have a build.gradle file, in which you need to include your dependency. It would look something like:
dependencies {
implementation 'commons-codec:commons-codec:1.14'
}
This lets Gradle know that you have a dependency to version 1.14 of commons-codec which your codes need to build and run.
This will automatically be downloaded from a remote repository, which you also can specify in your build.gradle file:
repositories {
mavenCentral()
}
This tells gradle to download the dependencies from Maven Central, which probably is the most typical Maven/Gradle repository and most likely hosts most dependencies you would need.
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.
Question
I have an internal maven repository in a shared folder say s:\mvnrepo – it's just a convention for a directory layout after all. Now I want to install a library com.example.lib:lib:1.0.0 and its dependencies from another external maven repository into s:\mvnrepo with the hypothetical command
mvn installlib com.example.lib:lib:1.0.0 -Dinto=file:///s:/mvnrepo
That would be a dream! Is such a thing possible?
(I don't have high hopes seeing as everything maven related is always so unapproachable and complicated...)
Supplemental Information
Now, I know there are maven repository management systems like Nexus but I really do think my use case should not require them. I also know about the deploy-file goal but it doesn't install transitive dependencies into the specified repository.
I also thought about simply creating a dummy project that has the specific library listed in its pom.xml. Then just execute mvn install -Dinto=file:///s:/mvnrepo. The problem is that the install goal apparently does not have an option to specify the repository directory (i.e. -Dinto is purely hypothetical).
I found out that it is possible to download a library and all its dependencies with Intellij. That's great but Intellij really only downloads the jars and does not create a maven compatible directory structure (i.e. there are no poms downloaded nor are the jars in a group subfolder etc.).
Background information
For work we want to have an internal maven repository such that it is possible to build an application on a freshly installed server that does not have an internet connection while still being able to specifiy dependencies in the gradle file as if we would use an external maven repository like jcenter (resp. bintray). So the gradle file we use would look something like this:
repositories {
// jcenter() // we don't want that
mavenUrl 'file:///s:/mvnrepo'
}
dependencies {
compile 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0'
}
Now, I downloaded the sdkmanager plugin jar and its pom file from mvnrepository.com and used something like
mvn deploy:deploy-file -Dfile=sdkmanager.jar -Dpom=sdkmanager.pom -Durl=file:///s:/mvnrepo
All fine and dandy, the sdkmanager plugin is installed into s:\mvnrepo with the correct directory layout and gradle even picks it up! But gradle is not quite satisfied, you see. It demands the jarchivelib which is a dependency of com.jakewharton.sdkmanager:gradle-plugin:0.12.0 (see the page on mvnrepository.com where jarchivelib really is listed as a dependency of the sdkmanager plugin). Now, I could repeat the fun and download jarchivelib and its pom from mvnrepository.com, deploy it and so on. Thinking about it... that does not sound like fun at all! So now you see my concrete use case and maybe you could suggest an even better approach than what I seek for in my question.
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.