scope "provided" gives install error in maven - maven

I am trying to install a Maven distribution from sourceforge (jtmt.sf.net) which provides a POM. Hoewever
mvn install
throws the error:
[ERROR] 'build.plugins.plugin[org.mortbay.jetty:maven-jetty6-plugin].depende
ncies.dependency.scope' for org.apache.geronimo.specs:geronimo-j2ee_1.4_spec:jar
must be one of [compile, runtime, system] but is 'provided'. # line 653, column
20
The pom contains the code:
<!-- For web development with Jetty6 -->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty6-plugin</artifactId>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>8081</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-j2ee_1.4_spec</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</plugin>
I am assuming the POM worked in the past though the project is somewhat dormant now.
Is there some switch I should set when installing? (I am using mvn 3.0.3). FWIW the distrib has checked out a very large number of libraries in lib/ .

The project was probably working with Maven 2. Maven 3 is much more picky about scopes in plugins, and scope provided is no longer allowed in plugin dependencies. You can try:
removing the dependency entirely and rebuilding (scope provided means something should already make it available anyway)
removing just the <scope> tag (to make it a simple compile dependency)
if nothing helps, you can try building it with Maven 2
The reason provided is now disallowed in plugins is that provided is really for dependencies provided by the environment (e.g. app server) at runtime. Jetty is a special case - it's an app server used frequently as a plugin.

Related

Maven + AspectJ/SpringAOP + Lombok + Surefire = test broken in a specific scenario

I have an interesting problem in a project where all of the technologies mentioned in the title are used. I've been able to track it down up to the diagnosis (the test classpath prepared by Surefire), but I don't understand whether it can be fixed and how. It's not a showstopper, indeed it's a minor issue for me, but I'd like to solve it anyway.
First a rough description.
The problem is related to executing tests in a specific module of the project, and only in a specific way.
Everything works (tests pass) when I run from the master pom level:
cd ${projHome}
mvn install
Everything works (tests pass) when I run:
cd ${projHome}/modules/CoreImplementation/
mvn test
That means that I can build and test with no problems, the same for my Jenkins, and NetBeans can run tests from the IDE when I need them.
But that module fails testing when I run from the master pom level:
cd ${projHome}
mvn test
with this error:
java.lang.NoSuchMethodError: it.tidalwave.northernwind.profiling.RequestProfilerAspect.aspectOf()Lit/tidalwave/northernwind/profiling/RequestProfilerAspect;
at it.tidalwave.northernwind.frontend.ui.spi.DefaultSiteViewController.processRequest(DefaultSiteViewController.java:82) ~[classes/:na]
at it.tidalwave.northernwind.frontend.ui.spi.DefaultSiteViewControllerTest.must_call_some_RequestProcessors_when_one_breaks(DefaultSiteViewControllerTest.java:161) ~[test-classes/:na]
Running mvn test as a second pass (after a mvn install -DskipTests) happens to be the way Drone.io and Travis do their job. While I could change their configuration, I'd like to stay with the standard configuration and fix the problem if possible.
The diagnosis in short and my question.
Now, the question in short (details are further below). I was able to track down the problem to different ways in which Surefire prepares the classpath to execute the tests.
When I run mvn install the classpath is:
${repo}/org/apache/maven/surefire/surefire-booter/2.16/surefire-booter-2.16.jar
${repo}/org/apache/maven/surefire/surefire-api/2.16/surefire-api-2.16.jar
${projHome}/modules/CoreImplementation/target/test-classes
${projHome}/modules/CoreImplementation/target/classes
${projHome}/modules/Core/target/it-tidalwave-northernwind-core-1.1-ALPHA-37-SNAPSHOT.952b0c8bdc77.jar
${repo}/it/tidalwave/thesefoolishthings/it-tidalwave-role/3.0-ALPHA-1/it-tidalwave-role-3.0-ALPHA-1.jar
${projHome}/modules/Profiling/target/it-tidalwave-northernwind-core-profiling-1.1-ALPHA-37-SNAPSHOT.952b0c8bdc77.jar
${repo}/org/apache/commons/commons-math3/3.0/commons-math3-3.0.jar
…
When I run mvn test (from the project home) the classpath is:
${repo}/org/apache/maven/surefire/surefire-booter/2.16/surefire-booter-2.16.jar
${repo}/org/apache/maven/surefire/surefire-api/2.16/surefire-api-2.16.jar
${projHome}/modules/CoreImplementation/target/test-classes
${projHome}/modules/CoreImplementation/target/classes
${projHome}/modules/Core/target/unwoven-classes
${repo}/it/tidalwave/thesefoolishthings/it-tidalwave-role/3.0-ALPHA-1/it-tidalwave-role-3.0-ALPHA-1.jar
${projHome}/modules/Profiling/target/unwoven-classes
${repo}/org/apache/commons/commons-math3/3.0/commons-math3-3.0.jar
…
The different portions are the indented ones. In the former case, SureFire uses the classes directory (forget for a moment that in my case they are named unwoven-classes) only for the module under test, and the installed jar files for every dependency. In the latter case, it seems to be using classes for all dependencies in the reactor.
The reason for which this difference in the classpaths gives me troubles is explained below in the "Gory details" section. In short, that unwoven means that they contain bytecode not augmented by AspectJ, hence the methods that can't be found at runtime.
I'm running with SureFire 2.16, but I've also tried the latest 2.19 with no changes. Being able to force SureFire to always use jar files for dependencies would fix my problems. If you have the answer, you can stop reading my post here.
Gory details (just for curiosity).
The faulty module artifactId is it-tidalwave-northernwind-core-default and it depends on aspects available in it-tidalwave-northernwind-core-profiling - that's where the offending RequestProfilerAspect is. The aspect library dependency is both in the regular dependencies of the faulty module and in the configuration of the aspectj plugin:
<dependency>
<groupId>it.tidalwave.northernwind</groupId>
<artifactId>it-tidalwave-northernwind-core-profiling</artifactId>
</dependency>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<aspectLibraries combine.children="append">
<dependency>
<groupId>it.tidalwave.northernwind</groupId>
<artifactId>it-tidalwave-northernwind-core-profiling</artifactId>
</dependency>
</aspectLibraries>
</configuration>
</plugin>
</plugins>
</build>
AspectJ integration is by means of the following profile in a Super POM, which is activated in the build, whose relevant part is:
<profile>
<id>it.tidalwave-aspectj-springaop-v1</id>
...
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>compile</phase>
<configuration>
<outputDirectory>target/unwoven-classes</outputDirectory>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<configuration>
<outputDirectory>target/unwoven-test-classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
...
The aspectj plugin is configured in the profile to statically weave binaries in the unwoven-test-classes directories. The reason for this approach is that it's the only feasible solution AFAIK to have both Lombok and AspectJ work together.
Now, back to the two classpaths described above: the fact that SureFire is using unwoven-classes means that it's pointing to bytecode that has not been augmented with AspectJ methods, hence the error.
References
The project is a FLOSS one and can be found at
https://bitbucket.org/tidalwave/northernwind-src
or
https://github.com/tidalwave-it/northernwind-src
A changeset where the problem can be reproduced is f98e9a89ac70138c1b6bd0d4570a22d59ed71be6. JDK 1.8.0 is required to build the project (even though it doesn't use Java 8 code yet).
The SuperPOM can be found here:
https://bitbucket.org/tidalwave/thesefoolishthings-superpom-src

a dependency to be in classpath only if run a plugin

For development I run application using jetty through maven (jetty-maven-plugin) and for all other deployments I use tomcat,
I want jetty web-socket(javax-websocket-server-impl) libs added to the classpath on if I run my app using jetty maven plugin, in tomcat these are inbuilt so I need not tell maven to grab these libs.
so to restrict these libs only for jetty maven plugin I added these libs inside
jetty-maven-plugin
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
<configuration>
<webAppConfig>
<contextPath>/myproject</contextPath>
</webAppConfig>
</configuration>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server-impl</artifactId>
<version>9.1.0.v20131115</version>
</dependency>
</dependencies>
</plugin>
this should add the jetty websocket libs to the classpath only if I run the plugin, but Its not,and I keep getting class not found, and if I add this to main dependencies in the pom it works, but i cannot do this because I dont want jetty libs in my deployment file when deployed in tomcat, please correct me, tell me how to restrict these libs only to the execution of this plugin.
The dependency will only be available for the plugins execution, not for the application. From the pom plugin documentation:
dependencies: Dependencies are seen a lot within the POM, and are an element under all plugins element blocks. The dependencies have the same structure and function as under that base build. The major difference in this case is that instead of applying as dependencies of the project, they now apply as dependencies of the plugin that they are under. The power of this is to alter the dependency list of a plugin, perhaps by removing an unused runtime dependency via exclusions, or by altering the version of a required dpendency.
You can use profiles instead, to add the dependency to the class path dependencies when running on the development machine.

How to hot redeploy non-active maven project via jetty-maven-plugin

I'm trying to evaluate jetty for rapid development or project which is currently running on tomcat. My configuration looks like
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.3.v20140905</version>
<configuration>
<scanIntervalSeconds>3</scanIntervalSeconds>
<webApp>
<descriptor>${project.build.directory}/${project.build.finalName}/WEB-INF/web.xml</descriptor>
<resourceBases>
<directory>${basedir}/src/main/webapp</directory>
<directory>${basedir}/../SharedWeb/src/main/webapp</directory>
</resourceBases>
<allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
<contextPath>/test</contextPath>
</webApp>
</configuration>
</plugin>
I have main war depending on SharedWeb war via war overlay mechanism. I specify resourceBases for both maven projects so changes in resources are scanned automatically and reloaded on the fly and all working fine. Also when I compile classes in main war, jetty restarts automatically, reloading the latest changes. But when I try to change any class in SharedWeb project and compile it, the class is not reloaded. I'm just wondering if there is a way to make embed jetty to reload classes from SharedWeb automatically? I understand that jetty-maven-plugin uses SharedWeb war from local maven repository, so I need to install SharedWeb artifact before I can see any changes. So I don't have high expectations, but maybe I'm missing something.
Ivan,
The plugin is using the classes and resources from your dependency
war, NOT from the that you have added. The
simply tells jetty to watch that location and redeploy if something in
it changes - it does NOT put it onto the classpath.
You need to tell jetty to use the classes and resources from your
dependency war's project, NOT the war artifact.
So do something like:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.3.v20140905</version>
<configuration>
<webApp>
<!-- tell jetty to use the classes from the dependency
webapp project directly -->
<extraClassPath>${basedir}/../SharedWeb/target/classes</extraClassPath>
<!-- tell jetty to use both this project's static
resources, and those of the dependency webapp project -->
<resourceBases>
<directory>${basedir}/src/main/webapp</directory>
<directory>${basedir}/../SharedWeb/src/main/webapp</directory>
</resourceBases>
</webApp>
<scanIntervalSeconds>3</scanIntervalSeconds>
<!-- tell jetty to watch the dependency webapp project classes
dir for changes -->
<scanTargets>
<scanTarget>${basedir}/../SharedWeb/target/classes/</scanTarget>
</scanTargets>
</configuration>
</plugin>
Jan
Since there doesn't seem to be a good prior answer that is specific enough for this question (aka <scanTarget>) I'll just post this new one and tweak the title to make it easier to find in the future.
What you are looking for is <scanTarget>, as that will allow you to customize the scanning locations for changed content that will trigger a hot redeploy.
The jetty-maven-plugin intentionally does not set this up for custom <resourceBases> as there are far to many legitimate use cases where this can cause aggressive / too often / or infinite redeploys. It was decided that it was best to break from "convention over configuration" for <scanTarget> entries and allow the developers to decide what should be scanned for changes.
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.3.v20140905</version>
<configuration>
...
<scanIntervalSeconds>3</scanIntervalSeconds>
<scanTargets>
<scanTarget>${basedir}/../SharedWeb/src/main/webapp/</scanTarget>
<scanTarget>${basedir}/../SharedWeb/target/classes/</scanTarget>
</scanTargets>
</configuration>
</plugin>

How do I get maven to use the JNLP version naming convention?

I've been tasked with reducing the download size of one of our webstart apps. I've figured that a decent portion of the download is from all a largish library of jar files, and since we rarely update many of them, it seems the download will be reduced significantly using the JNLP Version Download Protocol. This should stop the continual re-download of the same jars when a new version of the app is released.
Now, the project is build with maven. Part of the process is automatically generating a JNLP file from a velocity template. The resources section of the JNLP file is populated by a $dependencies variable assumedly passed in by maven and looks something like this:
<jar href="lib/mainjar-0.1.40-SNAPSHOT.jar" main="true"/>
<jar href="lib/somejar-1.1.jar"/>
<jar href="lib/someotherjar-1.0.jar"/>
<jar href="lib/anotherjar-1.6.0.jar"/>
etc...
It seems to me that maven is using its standard naming convention and constructing the jar names from the artifactId and version tags out of the project pom files.
How can I get it to use the JNLP naming convention instead?
I can change the velocity template to cut the $dependencies variable up and re-combine it with the JNLP convention - but that's only halfway what I need since the actual jar names need to be changed too.
The version download protocol article is about speeding up the check that resources are up to date. Although it may be useful as well, it is not the part that prevents re-downloading of the same files.
Webstart-maven-plugin can take care of versioning of the jars for you and they declare they use the version protocol as well. See http://www.mojohaus.org/webstart/webstart-maven-plugin/jnlp-mojo.html#outputJarVersions
My personal experience differs from what the docs say. It adds the version attribute for jars in the resulting jnlp and does not set the jnlp.versionEnabled property, which seems to be required for the version download protocol. Either way JWS works as I would expect - files are not re-downloaded when their version does not change.
Plugin setup:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>webstart-maven-plugin</artifactId>
<version>1.0-beta-6</version>
<dependencies>
<!--This dependency definition resolves class loading issue on Java 8 -->
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>keytool-api-1.7</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>jnlp-download-servlet</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectoryName>/</outputDirectoryName>
<libPath/>
<sign>
<keystore>${basedir}/foo-key-store.jks</keystore>
<storepass>password</storepass>
<alias>foo-self-signed</alias>
<verify>true</verify>
</sign>
<unsign>true</unsign>
<jnlpFiles>
<jnlpFile>
<inputTemplate>template.vm</inputTemplate>
<outputFilename>foo.jnlp</outputFilename>
<jarResources>
<jarResource>
<groupId>foo.bar</groupId>
<artifactId>foo</artifactId>
<version>${project.version}</version>
<mainClass>foo.bar.Foo</mainClass>
<outputJarVersion>false</outputJarVersion>
</jarResource>
</jarResources>
</jnlpFile>
</jnlpFiles>
<gzip>true</gzip>
</configuration>
</plugin>
Excerpt from the generated foo.jnlp showing the version attribute of a dependency:
<jar href="commons-collections.jar" version="3.2.1"/>
And the file it references is named:
commons-collections-3.2.1.jar

Android compilation failure in maven

I am making an Android app, and have created a custom view to do some animation.
I have created a custom view, extending ImageView and implementing ValueAnimator.AnimatorUpdateListener.
When I try to compile this with maven it fails with "package android.animation does not exist"
However, when building within Intellij Idea it builds fine. After building in Idea it is even possible to run mvn install successfully.
The successful build running fine in the emulator, but not on my physical device.
When trying to start it up on the device I get:
Failed resolving Lno/derp/myapp/view/MyAnimatedView; interface 7 'Landroid/animation/ValueAnimator$AnimatorUpdateListener;'
Link of class 'Lno/derp/myapp//view/MyAnimatedView;' failed
Could not find class 'no/derp/myapp/view/MyAnimatedView', referenced from method no/derp/myapp.MainActivity.onCreate
and then
java.lang.ClassNotFoundException: no/derp/myapp.MyAnimatedView in loader dalvik.system.PathClassLoader[/data/app/no/derp/myapp-2.apk]
pom.xml:
<packaging>apk</packaging>
<name>My App</name>
<dependencies>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<androidManifestFile>${project.basedir}/AndroidManifest.xml</androidManifestFile>
<assetsDirectory>${project.basedir}/assets</assetsDirectory>
<resourceDirectory>${project.basedir}/resources</resourceDirectory>
<undeployBeforeDeploy>true</undeployBeforeDeploy>
</configuration>
<extensions>true</extensions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<target>1.6</target>
<source>1.6</source>
</configuration>
</plugin>
</plugins>
I am using the latest version of the SDK. A class importing the mentioned package does not compile, it is not just the view. The same happens with version 2.8.3 of android-maven-plugin (or maven-android-plugin as it was called)
Any ideas?
android.animation is available since API Level 11, you need set your dependency in your pom.xml to use 3.0+ to compile your code in command-line.
The reason why it works in Intellij is IDE usually use default.properties to resolve the SDK used to compile source code, I suppose you use the correct API level in your default.properties.
Hope this help.
It seems you are missing the configuration of the plugin for the platform/api level. Check out e.g. helloflashlight example of the official samples.
In your case you would have to add
<sdk>
<!-- platform or api level (api level 4 = platform 1.6)-->
<platform>4</platform>
</sdk>
with api level 9 or 10 or whatever you need. See the API level doc.
And for the compile plugin to have the right API you have to have the correct android dependency. You potentially have to use my Maven Android SDK Deployer to push the dependency into your local repository
Maven Android SDK Deployer helped since I got
<dependency>
<groupId>android</groupId>
<artifactId>android</artifactId>
<version>4.0_r2</version>
<scope>provided</scope>
</dependency>
But the application still crashes on my phone, same as before, "Link of .. failed". Which is natural, since I probably have Android 2.X on my phone.
The reason Idea compiles is because it has the Android SDK set manually, it does not use the maven plugin, I think.

Resources