Gradle is an excellent dependency manager. However, there does not seem to be an obvious way with the Java plugin to pull the source artifacts from an entire dependency tree.
Building with GWT requires .java source files, not .class bytecode files.
When declaring dependencies among my own Gradle projects, I can define a custom Gradle configuration and extend the Jar task type to produce a custom source artifact. From the parent project, I can then easily rely on the subproject's sources in a loosely-coupled way.
But what if my subproject then relies on some non-source dependencies from mavenCentral()? How do I get the parent project to pull the sources from those transitive dependencies (the whole tree), assuming they are available?
There isn't an easy way to resolve a configuration's source Jars at the moment. (You'd essentially have to reimplement what the eclipse and idea plugins do). The next Gradle version (1.12) will provide a new artifact resolution API, which will make this a lot easier.
Related
I would like to use a GitHub repo inside a Script I'm writing. The Script will run inside an application which requires that the Script has minimal dependencies. By this I mean it can have a dependency on a standalone .jar or library, but not on one that has further dependencies. This is a security measure. My Script needs to have a dependency on a GitHub project, but that project also has its own dependencies. Is there any way to compress that GitHub project and its chain of dependencies into one standalone library or .jar?
I'm using IntelliJ (most recent version) if that helps. The GitHub project I need to use can be one of the following:
https://github.com/RuedigerMoeller/fast-serialization
https://github.com/EsotericSoftware/kryo
I need it to serialize and deserialize large object structures very quickly and frequently, otherwise my program doesn't operate on current data.
EDIT: So I did solve this issue, the solution was to use the Maven Shade plugin to compile an uber or fat .jar of the Maven project. This allowed me to bypass the security measure.
Having a dependency on a GitHub repo is having a source dependency (which might declare itself binaries dependencies in its own repo).
You would need to fork that repo, and transform its maven project in order to generate a fat jar (with for instance the Shade plugin).
And you would need to publish that new artifact to an artifact repository (like your own Nexus) in order for your project to depend on it.
I am trying to add a dependency as jar file and that jar is shipped with all the classes which are needed for it to run.
compile files('lib/org.hl7.fhir.igpublisher.jar')
Along with that, I have few other dependencies which are added as maven dependencies.
compile ("ca.uhn.hapi.fhir:hapi-fhir-base:2.3")
Now I am facing a lot of issues related to class conflicts because same classes have been shipped with different versions.
In an ideal case, how should I solve this problem? I want to say that the local jar should always use its own files and other dependencies should ignore the local jar files.
Note:- I am using IntelliJ idea.
This is a tricky problem. There is only one classpath and multiple versions of the same class mean that only one of that versions is visible and the other ones are hidden.
One should generally avoid to declare dependencies on "fat jars" that contain their own dependencies. If possible, one should use the slim version without the dependencies (often both versions are published). If there is not alternative one can construct such a slim jar yourself by manually splitting up the jar file. It is also possible to control the structure by carefully ordering the dependencies on the classpath, but this is a little brittle.
I am using Maven and my configuration (which is most likely the default) produces this:
That means my compiled code is 4% of the file. Largest inflation was caused by the GitHub API library - I am strongly considering that I'll just drop it.
But my question is about the small file, not the big one. Maven creates it for a reason right? Could I maybe somehow distribute it and have it work on clients' computers? Why does it exist and what useful can be done with that?
Given your question, your Maven project is most likely a jar project that uses the maven-assembly-plugin to generate an uber-jar. In your output, there are 2 different files that are the result of 2 completely different process.
autoclient-3.0.jar is what's called the main artifact. This is the primary result of the Maven build. It consists of the compiled classes in your project alone, packaged into a jar by the maven-jar-plugin. You have this file because your project has the jar packaging. In Maven, the jar packaging automatically bind goals to build phases of the default lifecycle: among others, it includes an invocation of the jar:jar goal, which creates this main JAR. But you have to realize that this JAR only contains your classes. If you try to run the code, it will probably fail because the dependencies won't be there. What's its purpose if you can't run it then? Well, its purpose is to serve as a library for other projects, not as executable code.
Take, for example, a utility library that you would like to create: this library is not intended to be ran directly, it's intended to be used as a dependency for another project which will be executable. With the notion of transitive dependencies, Maven will automatically include in the buildpath of the other project your library and all its transitive dependencies. As such, your library does not need to embed its dependencies directly: they will be resolved correctly during the build of the other project.
autoclient-3.0-jar-with-dependencies.jar is what's called an additional artifact. jar-with-dependencies is a classifier that is used to distinguish this artifact from the main one. It is the result of the execution of the maven-assembly-plugin with the predefined jar-with-dependencies descriptor file. This artifact consists of the compiled classes of your project and all the direct and transitive dependencies of your project. An uber-jar (or fat jar) is really that: it aggregates all the dependencies and your code inside one big jar. The advantage is that you don't need to distribute separately the dependencies, they are already included in the JAR. But do note that its purpose is not to serve as a library, it is to be used as executable code.
Note that for a single project, it could make sense to keep both JAR: one intended to be used as a library (the main JAR) and the other intended to be used as runnable JAR.
I am developing a Java application using IntelliJ Idea 14.1.4.
If it would have been solely Java application, I would have known exactly how to structure the project in Idea:
A single Java project, containing several modules: One for each part of the application (JAR).There will be at most 4-5 JARs.
The dependencies between the modules are also known: Protocol does not depend on anything, everything else depends on Infrastructure, and so on.
Next, I would like to use Gradle scripting for managing the project. So my question is what is the best practice to structure the code in Idea?
Should I create a single Gradle Project and a Gradle module for each of the JARs?
Should I create a single Java project (or maybe empty project) and Gradle modules for each of the JARs?
Should I create a single Gradle project and each of the modules will be a Gradle's sub-project? Maybe it will be better to have an empty project and several Gradle modules because not all of the JARs are closely coupled?
Since I have never used Gradle before, I would appreciate any guidance for the best practices when combining both Gradle and Idea.
Thanks,
Guy
As long as possible, I would keep the code in one source repository. On the root, I would have an "empty" project not outputting anything. All your jar projects would be sub-projects (in Gradle terms). You include them via the settings.xml file located in the root project.
Each sub-project has its own build.gradle file. In those files, you can easily define the dependencies between your sub-projects, e.g.:
dependencies {
compile project(':subProject3')
}
For convenience, I often create a special export task to put all artefacts in one export/ folder on the root level so that you don't need to go through all those sub-folders to get your stuff.
task export(type: Copy) {
from project(':subProject1').jar
from project(':subProject2').jar
from project(':subProject3').war
into 'export/'
}
IntelliJ Ultimate 14 works fine with this approach. You can simply hit Make to compile everything. You might also want to configure your project settings to run gradle jar or gradle export during a make if you prefer.
I want to build a java project with several dependencies in gradle, some are jar dependencies from the maven central repository, some are other java project dependencies, but there is also a native JNI dependency. I've managed to build the native dependency with gradle as a seperate project.
Now I want to import the compiled .so library as a depedency in my java project. I thought it would work something like this:
dependencies {
compile project(':nameofnativedependency')
}
The project is also listed in my settings.gradle file. However, when I compile the project, I can get an error:
Could not determine the dependencies of task ':test
Configuration with name 'default' not found.
So something must be misconfigured. What is the right way (I hope there is one) to compile a native project and import the .so file in the calling project?
The Gradle native plugin uses the new rule based software model. Model elements are not instantiated until after build.gradle has veen processed, and once instantiated they are immutable. To access those elements, you need to put your code inside the components closure, and access model elements through the $ variable (bearing in mind that elements accessed that way will be instantiated, therefore immutable).
To integrate a java build with a native build, you will probably want to use the java software model plugins, instead of the legacy java plugin. I have been playing around with it, and have a buildscript that I'm starting to feel a little proud of, incorporating all of the steps from generating headers from class files, building libs, copying into src/main/resources to be bundled in the jar, then extracting and loading libs at runtime (though this part's not quite done yet; Scijava's native library loader is probably the way to go).