dependencies for a library jar using gradle - java

I am using gradle 6.7 and creating a library project which is compiled to a jar that is placed in my own s3 artifacts repository.
In my project I have dependencies to other artifacts and I use implementation dependency.
The jar is created (not a fat jar) and uploaded to the s3 repository.
When in another project I am using my library by fetching it as implementation dependency I am getting errors NoClassDef for other dependencies I used in my library, which means that no runtime is found for the dependencies I was using in my library.
My question is, whether it is a good idea to create a fat jar? I don't think that other libraries (e.g. springboot and others) are using fat jars, right? however when I use them as dependency other dependencies are found on runtime.
Does it mean that using implementation in my project for other dependencies is not the right way? shall I use something else? Could you please contribute a bit more about what is the right way?
Thank you

Check out the Java Library Plugin for gradle. It exists for this exact situation.
If a dependency of your library needs to be exposed to the consumer of your library, then you would use api instead of implementation. There is a nice section within the plugin documentation here that can be used to help you identify when to declare a dependency as api vs implementation.

Related

How to include dependency as a .jar in resources with gradle?

I'm trying to share a dependency between multiple jars. My solution to this would be to include the dependency as a .jar in each one and then load the most up to date one at runtime (in order to not have multiple identical shaded versions, and to include resources from that dependency).
Essentially, I'm trying to make the compiled jar include dependency.jar as a resource - how can I achieve this with gradle? Or is there a better way of accomplishing this? I don't want to pull the latest version of the dependency .jar from a remote server as this has to work offline.
The easiest way of adding a dependency to your project without Gradle accessing a remote repository is to simply add the file as a dependency directly:
dependencies{
implementation(files("/path/to/myJar.jar"))
}
If you only want to stay offline you can run Gradle with the "offline" command line switch when you are offline. See the documentation.
To share across multiple modules you can declare the same file dependency in each module's build file.
Any attempt to compare versions between modules and/or load a JAR at runtime sounds excessively difficult to me.

Spring boot: Will a library get dependency from the parent app/service

I am using spring-retry in my spring-boot service, as well as spring-boot library.
I Noticed this scenario to work:
Use spring retry logic in the library, but the spring retry jars are not imported in the library
Use the library in the parent service as a maven dependency.
The parent service imports spring-retry maven jars.
Is is normal for the library code to use the maven jars from the parent app ? and not need to import the jars itself ? My common intuition says it should, as the resulting compilation unit will have the dependencies injected.. but not sure.
Sorry if this is a super naive question, but my searches did not give a good answer (maybe want using the right keywords)
I'm not sure I've got you right, probably this question should be rephrased.
So you say, that there is a "spring-boot library" that uses spring retry logic.
If so, this library has a maven module and it gets compiled into a regular jar, right?
But if so, if it uses classes/interfaces/annotations from spring retry library and doesn't have it on the compile class path how it gets compiled? I believe you do have this spring retry library in the dependencies but just don't notice (try mvn dependency:tree in the spring boot library module to see the dependencies)
Other than that - usually when you develop a library its intended to be reused by different applications, and if it has dependencies on its own, usually it should list them in the project's library pom. Also usually people who develop the library try to minimize the dependencies list of the library itself.
So if pom.xml of the library doesn't list the required dependencies it won't even compile.
Now in runtime, all the dependencies (including transitive of course) should be available to the spring boot application, otherwise the class that uses these dependencies might not load. But other than that, spring, being a runtime framework, doesn't really care how did the dependency find its way into BOOT-INF/lib folder - its expected to work as long as the dependency is there.

How to properly use any Java API

I have been trying to use the vget library/api to make my own youtube video downloader. The vget library can be found here: https://github.com/axet/vget
I have downloaded the zip on github and I imported the project into eclipse. However, I am confused to how I am supposed to properly use this API. Should I make a completely new project, and import the classes that I need or do I put my own source files in the project of the api?
I have read other threads concerning this problem. However, they all mention how a api is typically packaged in a JAR file, but in my case it is just files and classes. So I am confused to how I should properly use this api.
The vget project is a maven project. You can see that because it has a pom.xml file in the root folder of the project.
To use it, you don't even need to download the source, because the compiled jar files are already stored in the central maven repository. You can find more information about this here:
http://mvnrepository.com/artifact/com.github.axet/vget/1.1.23
(in general, you can use the http://mvnrepository.com/ site to search whether your library is available on the maven central repository. If it's even a mildly popular library, then chances are that it is)
What you need to do is to make your own project a maven project.
Here's a "5 minutes" starter guide that describes how to do that.
When you've done that, you just add the dependency on vget to your pom.xml file in the <dependencies> section:
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>vget</artifactId>
<version>1.1.23</version>
</dependency>
Since you are making use of a 3rd party software, and not extending it with your own logic, the way to go is to create a new project, which references the 3rd party software.
You then construct your application and make it do whatever you need it to do. When it comes to using logic which is available within the 3rd party logic, you would then simply delegate that call to the 3rd party library.
I have seen on the link you have provided, that this is a maven project. You have to execute a maven package command, or maven install, so that the jar file will be generated.
With this jar follow the Bill's instructions, and add it as external library to your claspath.
When you do this, you will be able to invoke methods of that api.
Let us know if you need some help doing this in eclipse.
If your project is a maven project, you can solve dependencies problems just adding the dependency written on Readme file to your pom file.
The easiest and most automatic way is to use something like maven, ant, or gradle, that will automatically download and put the jars in to your classpath if they are in the central repositories. For example, in the maven configuration file(pom.xml) you can add this to the dependency list:
VGet Maven Repository
These build tools also allow you to add external jars if needed.
If
I would suggest you get familiar with Maven. At the bottom there is a Maven dependency you just have to include into your pom.xml, and then you can use the extension immediately.
Maven is a build platform which organizes your project in a technical way (convention over configuration, e.g. code is in /src/main/java, tests are in /src/test/java). The proper way is it to create a Maven project in Eclipse (you have to install the plugin and download Maven as well) and put the dependency
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>vget</artifactId>
<version>1.1.23</version>
</dependency>
into your <dependencies> inside your pom.xml. After adding it, you project recognizes the additional package automatically.
Nobody tinkers by adding libraries manually. It's actually not professional to work without a build platform like Maven or Gradle.

Including a dependency to JAX-RS API on classpath when compiling - Neo4j

I am following Neo4j doc here: http://neo4j.com/docs/milestone/server-unmanaged-extensions.html to Unmanaged Extensions. I am not able to compile HelloWorld example given there. I am facing problem in creating jar file.
In the doc, There is a tip for compiling: "You will need to include a dependency to JAX-RS API on your classpath when you compile", I am not sure how to include this dependency with jar command. I am not using Maven.
You will have to download the jax-rs jars (and dependencies) from java.net:
https://jersey.java.net/download.html
I strongly recommend to use a build tool like maven, gradle or ivy to manage your dependencies though. Then you just have to add the java.net maven repository as source and it will be pulled automatically.

Java Dependency Management For Large Projects

I hope I can keep this question specific enough, my team at work is currently debating the best way to manage our dependencies for a huge project (150+ dependencies ~300mb).
We have two main problems
Keeping all the developers dependencies the same so we are compiling against the same files
Ensure the project (once compiled) is comliped against the same dependencies
The two ideas that have been suggested are using a BirJar (all dependencies in one file) and just adding a version number to it and using a shared folder and pointing everyone's machines at the same place.
Or making including all the dependencies in the jar when we compile it (a jar, of jars, of jars) and just have a project that "has no dependencies"
Someone also mentioned setting up an internal version of Ivy and pointing all the code to pull dependencies from there.
What are the best practices regarding massive dependency management?
Why don't you use Maven and its dependency management ?
You can specify each dependency, its particular version and its scope (compile-time, for testing, for deployment etc.). You can provide a master pom.xml (the config file) that specifies these, and developers can override if they need (say, to evaluate new versions).
e.g. I specify a pom.xml that details the particular jars I require and their versions (or range). Dependent jars are determined/downloaded automatically. I can nominate which of these jars are used for compilation vs. deployment etc. If I use a centralised repository such as Nexus I can then build my artefact (e.g. a library) and deploy that into Nexus, and it'll become available for other developers to download in exactly the same manner as 3rd party libs etc.
Incase you dont like/want to follow the Maven project structure...
If you already use Ant, then your best bet is to use Ivy for dependency management.
http://ant.apache.org/ivy/
It provides a rich set of ant tasks for dependency manipulation.
from : Ant dependency management

Categories

Resources