Removing a JAR from deployment - spring

I am working on a Spring Project on a JBoss server. I am facing a situation where I think removing a jar from the deployment may solve all the issues. But I want to keep the JAR in compile time so that I can use it in the classes.
I want to know how I can remove a jar from deployment only but keep it during the run time.
Probably, this is not the question to be asked on SO, as a matter of fact, SO is all about Coders and its main intention is to help us in solving a problem.
So, anyone ? How I can do this ?

If you are using Maven, the you need to mark the dependency as provided.
For example
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>provided</scope>
</dependency>
If you are using Gradle the corresponding element would be providedCompile. The code would look like:
providedCompile 'log4j:log4j:1.2.17'
For an Eclipse based build, check out this SO post

Related

how does runtime instance deal with provided scope dependency?

i am interested in understanding maven scopes during build life cycle.
i understood that working with a dependency, like this one :
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
the javax.servlet-api jar will not be included in the final executable jar,
because the server is supposed to already possess the dependency.
ok, but how does it work ?
where is physically the util jar ? (javax.servlet-api.jar)
last question :
when we build a jar, how can we be sure the dependency can be tagged as provided scope,
so that the server already has it, for the run ?
It is actually up to you to make that sure. Maven does not know about it.
So if you know that your server provides certain dependencies (e.g. because you read the server manual), then you can mark them as provided.

What is correct Maven scope of findbugs annotations?

I want to use a library that has the following dependency:
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>2.0.3</version>
</dependency>
I read that FindBugs is for static analysis of Java code, so I though it isn't necessary to include in application. Is it safe to exclude the jar with <scope>provided</scope> or with an <exclusion>...</exclusion>?
One reason to exclude it is that there is a company policy against (L)GPL licence.
Yes, you can safely exclude this library. It contains only annotations which do not need to be present at runtime. Take care to have them available for the FindBugs analysis, though.
Note that you should also list jsr305.jar, like this:
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
Both JARs are required to make these annotations work.
Check the most recent findbugs version in Maven Central.
FindBugs is provided under the LGPL, so there should not be any problems for your company. Also, you are merely using FindBugs; you are not developing something derived from FindBugs.
In theory, it should be entirely safe (as defined in the OP's clarifying comment) to exclude the Findbugs transitive dependency. If used correctly, Findbugs should only be used when building the library, not using it. It's likely that someone forgot to add <scope>test</scope> to the Findbugs dependency.
So - go ahead and try the exclusion. Run the application. Do you get classpath errors, application functionality related to the library that doesn't work, or see messages in the logs that seem to be due to not having Findbugs available? If the answer is yes I personally would rethink using this particular library in my application, and would try to find an alternative.
Also, congratulations on doing the classpath check up front! As a general practice, it is a great idea to do what you have done every time you include a library in your application: add the library, then check what other transitive dependencies it brings, and do any necessary classpath clean-up at the start. When I do this I find it makes my debugging sessions much shorter.

In Maven, how can I exclude all transitive dependencies from a particular dependency?

I want to exclude all transitive dependencies from one dependency. In some places I've seen it suggested to use a wildcard for that
<dependency>
<groupId>myParentPackage</groupId>
<artifactId>myParentProject</artifactId>
<version>1.00.000</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
When I do that I get a warning:
'dependencies.dependency.exclusions.exclusion.groupId' for myParentPackage:myParentProject:jar with value '*' does not match a valid id pattern. # line 146, column 30
The declaration itself is successful though: The transitive dependencies really are ignored in my build.
I've also found a old feature request that does request exactly this feature
So now I don't know if this is a deprecated feature that I shouldn't use, if the warning's wrong, or of the feature hasn't been completely implemented yet (I'm using Maven 3.0.4) ...Does anybody know more about this?
This is a supported feature in Maven 3.2.1 - see 'Transitive dependency excludes' section in the release notes.
I hate getting Maven warnings myself. I've seen the wildcard approach but have avoided it. Run a mvn dependency:tree goal, discover the top-level dependencies belonging to the artefact in question and exclude each one individually (hopefully the list isn't so vast). This is by far the safest way to approach this problem.
As to my knowing, this feature does not yet exist. In the feature request you sent, you can see it's status is still "Unresolved".

Correct way to declare multiple scope for Maven dependency?

I have a dependency that I want to use in test scope (so that it is in the classpath when I am running unit tests), and in runtime scope (so that I can contain that in WAR/EAR/other packaging for deployment, but not affecting transitive dependency lookup for dependent artifacts).
A real life example is SLF4J's implementation JARs (e.g. Logback). I want it to exist in the classpath when I am running tests, and I want it to be included in my WAR/EAR, but I don't want project depending on my project to include that in transitive dependency lookup.
I tried to use <scope>test,runtime</scope> but Maven 3 produces a warning:
[WARNING] 'dependencies.dependency.scope' for org.slf4j:jcl-over-slf4j:jar
must be one of [provided, compile, runtime, test, system] but is 'test,runtime'.
What is the right way for declaring the dependency scope in such a case?
The runtime scope also makes the artifact available on the test classpath. Just use runtime. (See the Maven documentation.)
To avoid having the dependency resolved transitively, also make it optional with <optional>true</optional>:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback</artifactId>
<version>0.5</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
You can only define one scope value per <scope/> tag.
I'm afraid what you'd like to do cannot be achieved by merely using a scope. If you define a scope of test, it will only be available during tests; if you define a scope of provided, that would mean that you would expect that dependency for your project to be resolved and used during both compilation and tests, but it will not be included in your WAR file. Either way, it's not what you would want.
Therefore, I would recommend you have a look at the maven-assembly-plugin, with which you can achieve it, but it will still require some playing around.
Not sure if this would still help someone who is still looking for a simple way to do this - https://howtodoinjava.com/maven/maven-dependency-scopes/ this link helped me add the correct scope. Here is the summary of mapping of scopes and the phases where we need the dependencies.
compile - build, test and run
provided - build and test
runtime - test and run
test - compile and test
So, when I needed the dependency during test and runtime, I gave the scope as "runtime" and it worked as expected.
Declaring a dependency with a scope of runtime ensures that the library is not available during compile time.
Declaring the dependency as optional causes a break in the dependency resolution process; projects depending on your libraries will need to explicitly include the dependencies themselves.
So the correct way to declare this would be:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.13</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

Maven Learning Questions

In eclipse I've installed m2e plugin. I am trying to understand how do you know the names of properties for dependencies to add to pom file?
Say for instance how do you know which artifact id to use?
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
why here say aspectjrt in artifact id?
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
and here same as group id ??
is there any pattern?
say my project is missing
org.hibernate.Query;
org.hibernate.Session;
org.hibernate.SessionFactory;
and in maven dependencies folder I have hibernate-core-3.6.0.Final.jar which effectively contains everything except those 3.
Do you write these .pom yourself?
I am betting that for student project I will have to stick with manually adding hundreds of libraries... otherwise I will fail trying to learn it :-)
You know what groupId:artifactId:version (we call these coordinates) to use by which artifact you want. Most often, you find out which artifact you want by reading it in the project's documentation, especially for projects with a large number of artifacts, some of which might contain optional addons.
aspectjrt is short for AspectJ RunTime.
GroupId and artifactId are defined by the creators of the library in question. There's no universal pattern because there's no one central coordinator. There are some conventions that have evolved, though. Generally, the groupId is at least partly the reversed domain name, like the first part of a Java package name is: org.hibernate, org.apache, org.springframework... The artifactId distinctly identifies the role of that particular artifact in the group it belongs to, like spring-core, spring-tx, spring-jms, etc. You can get an idea of what groupId's and artifactId's look like by searching Maven Central for some of the libraries you know.
If you're missing org.hibernate.SessionFactory, then you don't have hibernate-core-3.6.0.Final on your classpath. If you have that on your classpath, then you're not missing the SessionFactory class. Those three classes you mentioned are most definitely in that artifact, as you can see from searching for the class in Central. If you still doubt, do a jar -tf hibernate-core-3.6.0.Final.jar and check out the contents yourself. I promise it has those classes.

Resources