I have a JAR. It is not a FAT JAR. It only contains my classes. But my JAR has a dependency upon azure-servicebus. I don't want to add azure-servicebus to my jar and make it a fat jar.
I just want that when the project adds my jar, it should download azure-servicebus automatically.
I am using Maven to create a jar (without dependencies).
How do I specify that? Is this possible?
edit:
I want the project that is adding my jar as a dependency should download azure-servicebus WITHOUT project having to add dependency for azure-servicebus or me packaging azure-servicebus within the jar file.
Assuming you already have a maven structue in your project, you would add the following line to your pom.xml:
<!-- https://mvnrepository.com/artifact/com.microsoft.azure/azure-servicebus -->
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus</artifactId>
<version>1.2.12</version>
</dependency>
If you don't have a maven structure, you'd need to generate one. This usually can be achieved within the IDE you're using.
If you want the resulting jar not having the service-bus, you can make the dependency some kind of compile only, which would be more or less a duplicate of this question: Is there a Maven "compiler-only" scope for dependency artifacts .
However, this would imply that your target runtime has to include the definition for the classes in some way (via -cp switch maybe).
From my POV: If you need a dependency to run your program, include it as long as the licence allows that.
If I understand you correctly, the structure you are talking about is:
some-project depends on your-jar which depends on azure-servicebus.
If some-project declares a Maven dependency on your-jar, then it gets azure-servicebus automatically as dependency because Maven does transitive dependency resolution. So when you build some-project, azure-servicebus will be on the class-path and if some-project is a WAR/EAR, than azure-servicebus will be part of that WAR/EAR.
I asked this question without knowing something very important.
When jars are put into artifactory, a corresponding .pom file also has to be placed alongside it (outside of the directory). This pom file is what tells the dependent project that the jar you are dependent upon, requires so and so dependencies itself.
This answer helped me understand:
https://stackoverflow.com/a/50002072/4828463
Thanks to everyone who tried.
Related
I have a Maven based project, and I use IntelliJ. The pom.xml file probably contains dependencies that I don't need. How can I find which Java files (in particular the import statements) that need a specific dependency in the pom.xml file? Alternatively, how can I find which dependencies I don't need in the pom.xml?
I have tried to comment out a dependency from pom.xml, build the project and look what breaks. In at least one case, I saw no compile time problems, but there was a runtime problem. This method is also more effort than I want.
I have also tried to find information in the IntelliJ Project explorer, section "External Libraries". But the items listed there are not always present in the pom.xml file. Each versioned item there expands to a tree with a jar file on top, and I can ask IntelliJ about the usage of the contained items. I have found the usage of some packages contained in jar files, but the number of packages to investigate simply becomes too large.
Here is a dependency that I want to know if I need or not:
<!-- https://mvnrepository.com/artifact/com.googlecode.soundlibs/mp3spi -->
<dependency>
<groupId>com.googlecode.soundlibs</groupId>
<artifactId>mp3spi</artifactId>
<version>1.9.5.4</version>
</dependency>
This particular dependency results in three items in the External Libraries list (there are two sub dependencies apparently). Asking IntelliJ for usage of these libraries, I can't find any usage in my own files. But if I remove the dependency from the pom.xml file, I get runtime problems.
Maven offers you the dependency:analyze goal which gives you the artifacts that are declared in your pom but not used by any part of your source code. Beware, though, that there may be dependencies that are only used at runtime.
I have a project that generates some classes and resources that should then be packaged into a jar.
The class that does the generating has several dependencies. The generated classes have no dependencies.
My initial solution was to use the maven assembly plugin to only include the generated files. Unfortunately, the packaged pom includes all the dependencies required to do the generation. Consumers of this jar pull in a bunch of unnecessary dependencies.
I looked into the maven shade plugin. I compile once, run the generator class with mojo's exec plugin, the compile a final time. Then shade of course runs in the package phase. It creates a dependency-reduced-pom.xml without the excessive dependencies. So run mvn clean package and look in target/foo.jar. I expect the jar in the meta-inf folder to be the reduced dependency jar. But it's the full pom. I don't know how have the generated pom replace the one that is packaged.
Another poor solution I tried was using multiple profiles with their own dependency section. I run maven once with the generating profile, then again with the packaging profile. This works, but sucks because you have to run multiple maven commands. It's not jenkins friendly.
Am I going about this the wrong way? How should I go about arranging a project that generates some code and some text files that are then packaged in a maven friendly artifact?
1) One possibility is to make all your dependencies <optional>true</optional>.
The pom will still have the dependencies but the projects using your library won't try to download them.
2) Use plugin dependencies with the exec plugin.
That works well if the generator class is defined on another project.
Ideally you would call your generator using a plugin and avoid adding those dependencies to your project. That may not be worth doing depending on what your project is for and how reusable your generator has to be.
3) If you are using maven-shade-plugin the dependency-reduced-pom.xml is normally used. Check your .m2 repository to see the contents of the pom that is copied there when you do mvn install. It's likely that its contents will match the dependency-reduced-pom.xml
I have a Java that contains many main classes. I want to create a Jar with only one main class and only its dependencies. I want only the code of the main class and dependencies to be included in the jar. I use Maven to make my jar.
The maven way is to have maybe one parent project, and for every application one module project. Every single application project has one Main-Class specified in the META-IBF/MANIFEST.MF, and separate minimal dependencies. Probably need to have one or more library project for internal dependencies.
/all
/lib-a
pom.xml --> lib-a-0.1-SNAPSHOT.jar
/lib-b
pom.xml --> lib-b-0.1-SNAPSHOT.jar
/app-m
pom.xml --> app-m-0.1-SNAPSHOT.jar
/app-n
pom.xml --> app-n-0.1-SNAPSHOT.jar
...
pom.xml --> all-src-0.1-SNAPSHOT.zip
--> all-0.1-SNAPSHOT.jar
The applications generate a manifest with a Main-Class: ... entry.
The dependencies are defined per application.
You might have the idea of having just one project, and a smart maven plugin that handles local dependencies, but why.
You could keep all sources in one project, say generating as artifact a zip with sources.
And every application project could take a specific list of sources from the zip. Hard.
If you indeed want something very customized, I think going back to ant + ivy would be more effective.
So I am working with the Proguard Plugin to obfuscate one of my jars before deploying it to Maven. My goal is to have only the obfuscated jar deployed to Maven.
Currently I noticed that two jars get deployed, myJar.jar and myJar-small.jar (the obfuscated one from proguard). I have confimed that my Nexus index contains both of them and a single pom after being deployed. The problem is that when I add myJar as a maven dependency to another project, the unobfuscated jar is pulled into the project, not the obfuscated jar.
Is there way to only upload the obfuscated jar or to specify which jar should be pulled into other projects?
I have looked at the Proguard options here, but not been able to find much that helps.
For your own use, when you define your dependency, add the classifier tag with a value of small.
<dependency>
<groupId>myGroup</groupId>
<artifactId>myJar</artifactId>
<scope>test</scope>
<classifier>small</classifier> <!-- <<<<<< like this <<<<<< -->
</dependency>
For publishing, you can manually deploy the artifact with a new classifier as demonstrated here:
http://maven.apache.org/plugins/maven-deploy-plugin/examples/deploying-with-classifiers.html
I assume you use the Maven ProGaurd Plugin (http://pyx4me.com/pyx4me-maven-plugins/proguard-maven-plugin).
If you leave the attach parameter on its default false value and do not set anything for outjar, the original artifact is overriden by the obfuscated one. Thus, only the obfuscated version will be deployed.
In new Maven projects in IntelliJ, I see 2 ways of declaring new dependencies:
Manually editing the pom.xml file, adding a <dependency/> declaration.
This automatically (maven auto-import is on) adds Maven: ... entries to the project .iml file and all is well.
Using the File -> Project Structure -> Dependencies menu. This only creates entries in the .iml file.
This seems like unwanted behavior. IntelliJ doesn't overwrite the .iml file when importing the pom.xml Maven file, but merges dependencies from the pom.xml and additionally-defined ones from the .iml.
I want to enforce a single way of adding dependencies in my team (using pom.xml only, for external mvn builds), and the ability to bypass the pom.xml and directly add dependencies to the .iml creates the illusion of a valid build (when in fact, it is not).
Am I missing something? How can I enforce one way of adding dependencies? Is there a way through which IntelliJ will add dependencies to the pom.xml file instead of the .iml files?
EDIT
In this question (IntelliJ IDEA + Maven what is the need for dependency entries in an iml file?) it is claimed that
This can be also used to experiment with dependencies without changing the pom.xml. Note that all the modifications you make will be reverted on next Maven import.
But this is not the behavior I see. The .iml file doesn't get reverted, but merged.
It sounds like you need a continuous integration environment.
This won't stop your team members adding dependencies in the wrong place, but it will ensure that is caught very early and flag it up that they need to add it to your pom, then it just comes down to education.
Pom.xml is only to be used by Maven, IntelliJ does pick up the dependencies from the pom.xml if you have configured your IDE properly. If you however, want to use maven solely, you can add the jars to your local maven repo and then call them from your pom.xml normally via the <dependency> tag.
You can learn how to add local jars here.