Store Nexus/Maven artifact with no version number - maven

I need to store an artifact in Maven/Nexus but when it's pulled down it must not have a version number at the end.
Before you berate me, point your scowl at Oracle.
I have comm.jar (Oracle comm port driver). I've put this in my nexus server & it comes down as comm-1.0.jar. But the JAR contains the following code:
if(streamtokenizer.ttype == -3
&& (i = streamtokenizer.sval.indexOf("comm.jar")) != -1)
It's hard coded to use its own name to know where to find the configuration file that goes with it. The jar is signed so I can't make changes to it.
So... how to I store a jar in Nexus and not have an extension number on it ?
This isn't the exact answer to my question but it does solve my problem.
I called my jar "comm.jar-1.0.2.jar" The code looks for 'comm.jar' in the file name so now it finds it!
ok, so it a fudge and I'm lucky the internal code is just looking for indexOf. but it works!
Thanks to everyone for there advice on this!
Jeff

This isn't a complete answer, more a collection of thoughts on how you might approach this.
I think you will need to declare your dependency with the version number present, to ensure Maven is happy to resolve the artifact and build it. So, the trick will be ensuring the aritfact is renamed before it is bundled in your finished product.
The Maven dependency:copy-dependencies goal has a stripVersion parameter that might come in useful. I suspect you can use this to rename the JAR correctly, perhaps as part of an assembly (ensuring the depedency is moved to a directory that is part of the classpath).
Such a plan may well break your development environment, however. Perhaps you can get around that by fudging a JAR file with the right name?

If you want it to work with a war project then you can use the File Name Mapping to strip the version.
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<outputFileNameMapping>#{artifactId}#.#{extension}#</outputFileNameMapping>
</configuration>
</plugin>
</plugins>
</build>
The dependent jars will as normal end up in WEB-INF/lib but now without the version.
But from your question it is hard to tell what your end product is, war, jar, zip, ...

Related

Maven install goal does not generate pom for modules

I'm running a multi-module maven project and have an unexpected behavior. First time I'm seeing this...
My parent module configures the install plugin, defining its classifier.
<plugin>
<artifactId>maven-install-plugin</artifactId>
<configuration>
<generatePom>true</generatePom>
<classifier>${env}</classifier>
</configuration>
</plugin>
<!-- ... -->
<modules>
<module>webapp-formation</module>
<module>db-formation</module>
</modules>
But when I'm running mvn install the .pom files are not generate for my modules. Only my parent is associated with a .pom file in my repositories. Thus trying to browse to my module's artifact on Archiva (after running mvn depoy of course!) it simply fails. I can browse to the parent but not its children.
So... I need to add the undocumented attribute generatePom to my plugin configuration to have the .pom files generated --copied would be a better word actually-- for all my modules. --I said undocumented attribute because this attribute is documented only for the install-file goal which is not the one ran by default. The install goal is not expecting that attribute...
Of course, if I do not configure my install plugin --so not configuring the classifier-- I have no problem and all .pom files are generated properly.
For you guys, is that a normal behavior? Something that you have already seen? Or should I just file a bug?
Thanks,
Olivier.
What you describe as an undocumented attribute is simply wrong, cause the attributes are specific on a goal base which means the given configuration will not change anything, cause the generatePom attribute is only valid for install-file goal. So you can remove it.
In general such configuration does not make sense, cause if you have different environments you should go a different way. Just removed hte configuration with <classifier>${env}</classifier> as well and try to deploy via:
mvn clean deploy

Extract current folder name within maven pom.xml file

I am looking for a way to dynamically extract the current folder name within maven pom.xml file.
For Example:
if the pom.xml file is at /home/jenkins/workspace/bdms-ci/bdms-bcr/pom.xml
then bdms-bcr is the current folder.
See a code snippet:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<testClassesDirectory>../../bdms-ci-improve/${project.basedir}/target/test-classes</testClassesDirectory>
<classesDirectory>../../bdms-ci-improve/${project.basedir}/target/classes</classesDirectory>
</configuration>
</plugin>
${project.basedir} will bring the full path which is not good since only the current folder is needed.
I tried to work with MavenProject class from the maven api document:
${project.file.parentFile.name} or ${project.file.name}, but it didn't work.
remember it is maven multi project and everything has to be dynamically.
The whole issue is for jenkins ci build which use parallel-test-executor plugin. I would like to compile once in the main job and then all the other test execute jobs will will only test by looking into the compiled code.
Using maven 3.2.3
#guymi,
Seems like you should be able to simply use ${project.artifactId} or perhaps ${parent.artifactId}.
EDIT
Or does your artifactId name disagree with the directory it's stored in?
If so, that's possible but not good practice and should be avoided.
It is not possible to do it. simple as that.
A workaround solution is by using artifactId with the same name as folder name. then you can do:
../../bdms-ci-improve/${project.artifactId}/target/test-classes</testClassesDirectory>

How to ignore a Maven plugin

We have a groupId for Maven plugins:
com.company.maven.plugins
Unfortunately, when I created the first plugin in this groupId, I initially used the wrong naming convention.
maven-myplugin-plugin
The 1.x versions of the plugin used that name. When I realized this was wrong I changed the name to meet the correct convention.
myplugin-maven-plugin
Then I updated the version to 2.x.
In my local settings.xml file I use the pluginGroups to access my plugins from the command line. This particular plugin does not have to be specified in the pom file.
Unfortunately, when I try to access my plugin from the command line without scoping the name I always get the latest version of the incorrect naming convention. So, I get a 1.x version.
Can I tell Maven to ignore the maven-myplugin-plugin artifacts when accessing from the command line (i.e. mvn myplugin:mygoal)?
Some projects still use the old 1.x plugins, so I don't want to delete them from our repository. Also, we are using at least Maven 3.0.3.
It somehow seems that Maven3 resolves the prefixes from plugins in the order of
1. maven-myplugin-plugin
2. myplugin-maven-plugin
3. ... hard-wired groups ...
Following the official naming convention it should be the other way round imho. Nevertheless, I think you do not have a chance to get this fixed. I tried a set of things, basically playing around with the goalPrefix in the maven-plugin-plugin config. Installing a new version of the deprecated-named plugin with goalPrefix did not work. I guess one thing you could do is defining another prefix for your correctly-named plugin, e.g.:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.2</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
<goalPrefix>myplugin2</goalPrefix>
</configuration>
</plugin>
Another approach could be to adjust the old plugin's pom.xml, renaming it to something different. But this would imply that your colleagues would need a different execute a different mvn command. Or you can rename your current plugin - similar results.
If there is a better solution, I would also be interested!

Maven dependency:analyze thinks my JDBC JARs are "unused"

I'm using a MySQL connector JAR to make JDBC connections. My understanding is that I just have this JAR in the classpath, and it'll be dynamically loaded when I specify mysql: in the connection string.
I declare this dependency in my POM using <scope>runtime</scope>. When I run mvn dependency:analyze, it reports this artifact as "unused". I guess it can't determine that I'll need it through simple static analysis, fine, but surely that's going to be true of just about any runtime-scoped artifact, right? How can I convince Maven that this artifact really needs to be there?
dependency:tree will list all artifacts that are referenced by your pom files if that is what you are looking for. Otherwise you are likely out of luck. Maven openly declares that their dependency analyzer works at the bytecode level and will falsely report dependencies as unused in some scenarios.
A runtime-scoped dependency may or may not be used, it is impossible to tell with bytecode analysis (in fact, impossible to tell with most analysis I could think of). Maven has to decide to either assume they are used or assume they are unused and they went with the latter figuring the user could figure it out.
There is no option to tell Maven to treat runtime-scoped dependencies as used but you can manually add specific artifacts to the usedDependencies array in the configuration. Maven will simply assume those dependencies are used. You could also write your own dependency analyzer or find a 3rd party dependency analyzer that can handle this scenario.
==Update for comments==
You're right, it is quite new. The issue was fixed in version 2.6 which was released Nov, 25, 2012. It isn't yet in many of the public mirror repositories. You can find it here.
Since it is so new there are no examples of its usage however Maven follows some conventions. I would expect it to be declared as:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<configuration>
<usedDependencies>
<usedDependency>org.foo.bar:baz-tron</usedDependency>
<usedDependency>org.foo:whatsit</usedDependency>
</usedDependencies>
</configuration>
</plugin>
</plugins>
</build>

Maven: Force Jersey to use specific artifact version

I have a Maven repository where I load Jena TDB 0.9.3 (which depends on Jena ARQ 2.9.3), Jersey 1.8 and RMOnto 1.0. The point is, as you expected, to do some analysis on semantic datasets.
It looks like RMOnto has ARQ 2.8.7 built in, as in "hardwired". There isn't any explicit dependency in its pom file, yet the jar file contains a ARQ.class. It's very tricky because you won't notice it with Maven Enforcer Plugin and the like.
It looks like this causes Jersey to use RMOnto's ARQ version instead of the one defined in pom.xml. Here is a minimal example. When you run the test (checks whether or not ARQ.VERSION equals 2.9.3), it succeeds. When you build the project and deploy it on a Tomcat 7, you should see 2.8.7 as output.
Is this behaviour expected and why?
How could one force Jersey to use ARQ 2.9.3?
In case it's not possible, could one isolate RMOnto to use 2.8.7 while the rest of the source uses 2.9.3?
Thanks in advance!
You should define the ARQ 2.9.3 first in the dependencies list. By doing that you force your build to use that specific version. The dependency order is relevant when choosing what artifact to use.
Update
OK, I understand what the problem is.
The RMOnto jar is obviously shaded according to the pom: http://semantic.cs.put.poznan.pl/maven/put/semantic/RMOnto/1.0/RMOnto-1.0.pom.
Tomcat 7 loads the jars in WEB-INF/lib in an undefined order. This means that even if you define ARQ 2.9.3 to be first in your dependencies it will not be the case when the application is run in Tomcat. http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html
Good thing is that Tomcat always look in WEB-INF/classes before WEB-INF/lib for dependencies.
So what you can do as a work around is to make sure that the ARQ 2.9.3 version is added to the WEB-INF/classes folder. This can be done using the maven-dependency-plugin:
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.apache.jena</groupId>
<artifactId>jena-arq</artifactId>
<version>2.9.3</version>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<excludes>**/META-INF/</excludes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Your war as well as your exploded war will now contain all the classes from ARQ 2.9.3 in the WEB-INF/classes folder. They will be loaded before any jar-file that is in WEB-INF/lib folder.
NB: I have not tested this on Tomcat but I cannot see that it would not work.
NB2: This is a hack. Best thing would be to remove the ARQ packages out of the RMOnto jar.
You should file a defect report against RMOnto. Hard-wiring library code into a jar, instead of including it as a dependency you can manage in the POM, is definitely a bad idea that the code maintainer should fix.
If the files have been copied directly to the RMOnto .jar, the behaviour is expected.
In that case, I'd say the best bet is to hardcode it away, aka remove the ARQ files directly from the package. Opening up the RMOnto-1.0.jar package one can see arq files in the arq folder. What you'd need to do is open up the jar file (it's just a .zip), remove the ARQ files from there, store the edited RMOnto package in your version control / repository and refer to the edited package from there. Also, you'd need to add excludes statement to your pom for the old version of ARC and keep the dependency to the new version.
If you feel like it, it would be also good practice to remove the other dependencies that haven't been mentioned in the RMOnto's pom file, then add them in the RMOnto pom file (and rebuild, if you have the source code). This way Maven mechanism would be aware of them. The file seems to contain a lot of dependencies like this, which will cause headaches in the future.

Resources