We have been using Android API version 17 in a project and wish to upgrade to API version 19 because the application runs on Android 4.4.
We use Maven as our build environment. I have replaced all the occurrences of SDK version 17 to 19 in our AndroidManifest.xml. But I am having problems upgrading to the 4.4 platform through Maven.
I used the Android SDK Deployer tool to push the android-4.4 package into my local Maven repository. I then replaced the reference to android-4.2 to android-4.4 in our 'parent' POM.xml:
<dependencyManagement>
<dependencies>
<dependency>
<!-- <groupId>com.google.android</groupId> OLD -->
<groupId>android</groupId>
<artifactId>android</artifactId>
<!-- <version>4.2.2_r2</version> OLD -->
<version>4.4.2_r4</version>
<scope>provided</scope>
</dependency>
This change seemed to introduce a conflict. Another dependency is bringing in version 2.1_r1 of android package which is conflicting with the new 4.4.2_r4 package:
Excerpt from 'mvn dependency:tree':
.
[INFO] +- com.github.tony19:logback-android-classic:jar:1.0.10-2:compile
[INFO] | \- com.github.tony19:apktool-lib:jar:1.4.4-3:compile
[INFO] | \- com.google.android:android:jar:2.1_r1:compile
[INFO] | +- org.khronos:opengl-api:jar:gl1.1-android-2.1_r1:compile
[INFO] | +- xerces:xmlParserAPIs:jar:2.6.2:compile
[INFO] | \- xpp3:xpp3:jar:1.1.4c:compile
I noticed that if I move the <dependency> declaration of the 4.4 package above the logback-android-classic dependency declaration in pom.xml then our module will use the 4.4 dependency. However I don't think this is a proper fix, and I am running into various issues building the project as a whole.
Can those more experienced with Maven please advise on the correct way to resolve this?
Going through each affected module and adding an exclusion to the logback-android-classic dependency seems to have resolved it:
<exclusions>
<exclusion>
<artifactId>android</artifactId>
<groupId>android</groupId>
</exclusion>
<exclusion>
<artifactId>android</artifactId>
<groupId>com.google.android</groupId>
</exclusion>
</exclusions>
Related
I have a Google App Engine project that I'm building with maven. I added jax-rs to it by adding the following bom to my pom:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-bom</artifactId>
<version>0.73.0-alpha</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>2.27</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Also I needed these three dependencies:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<exclusions>
<exclusion><!-- Exclude this repackaged javax.inject. -->
<groupId>org.glassfish.hk2.external</groupId>
<artifactId>javax.inject</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<exclusions>
<exclusion><!-- Exclude this repackaged javax.inject. -->
<groupId>org.glassfish.hk2.external</groupId>
<artifactId>javax.inject</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
As you can see I have excluded some of the repackaged to get rid of some runtime warnings about duplicate classes being found. To be clear, every rest call using the jax-rs api's works fine and I don't see the warnings on google app engine itself, just locally. (full code at https://github.com/Leejjon/blindpool) When running it on the local jetty runtime using 'mvn appengine:run', it still complains about every json related class in the javax.json-1.1.jar and javax.json-api-1.1.jar.
Example
[INFO] GCLOUD: 2018-12-11 22:01:13.495:WARN:oeja.AnnotationParser:main: Unknown asm implementation version, assuming version 393216
[INFO] GCLOUD: 2018-12-11 22:01:13.780:WARN:oeja.AnnotationParser:qtp551734240-15: javax.json.Json scanned from multiple locations: jar:file:///C:/Users/Leejjon/IdeaProjects/Blindpool/backend/target/blindpool-1.0-SNAPSHOT/WEB-INF/lib/javax.json-api-1.1.jar!/javax/json/Json.class, jar:file:///C:/Users/Leejjon/IdeaProjects/Blindpool/backend/target/blindpool-1.0-SNAPSHOT/WEB-INF/lib/javax.json-1.1.jar!/javax/json/Json.class
When I look at my 'mvn dependency:tree' output I can see that my 'jersey-media-json-binding' dependency has both javax.json-1.1 and javax.json-api-1.1 in it. And they have classes that have the same names.
[INFO] +- org.glassfish.jersey.media:jersey-media-json-binding:jar:2.27:compile
[INFO] | +- org.glassfish:javax.json:jar:1.1:compile
[INFO] | +- org.eclipse:yasson:jar:1.0:compile
[INFO] | | +- javax.json:javax.json-api:jar:1.1:compile
[INFO] | | \- javax.enterprise:cdi-api:jar:2.0:compile
[INFO] | | +- javax.el:javax.el-api:jar:3.0.0:compile
[INFO] | | \- javax.interceptor:javax.interceptor-api:jar:1.2:compile
[INFO] | \- javax.json.bind:javax.json.bind-api:jar:1.0:compile
Full dependency tree (https://pastebin.com/JfwzavDX).
I have tried to exclude them but failed to do so in a way that didn't cause me to actually break my web app and get errors like: javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.ExceptionInInitializerError
TLDR: What dependency to I exclude here to get rid of the duplicate location warning thrown by the 'mvn appengine:run' command without breaking the jax-rs application.
Hoping for that jax-rs/maven/jetty/jersey/google app engine god to pass by and point me in the right direction :)
Overall applicatiom I'm using Apache HttpComponents dependency:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
But also another library uses this artifact, but different version (4.3.2, not 4.5.2):
<dependency>
<groupId>com.sendgrid</groupId>
<artifactId>sendgrid-java</artifactId>
</dependency>
The problem is that API between this versions is changed and I'm getting this error:
Caused by: java.lang.ClassNotFoundException: org.apache.http.ssl.SSLContexts
How I can say to maven not to override Sendgrid's version of HttpComponents (4.3.2) with 4.5.2?
EDIT: version of httpcomponents is specified in dependencyManagement section of parent pom
Given the following parent pom.xml section:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.sendgrid</groupId>
<artifactId>sendgrid-java</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
<modules>
<module>module-a</module>
<module>module-b</module>
</modules>
Indeed in module-a the dependency tree is the following, executing:
mvn dependency:tree
We get as part of the output:
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # module-a ---
[INFO] com.sample:module-a:jar:0.0.1-SNAPSHOT
[INFO] \- com.sendgrid:sendgrid-java:jar:2.0.0:compile
[INFO] +- org.json:json:jar:20140107:compile
[INFO] +- org.apache.httpcomponents:httpcore:jar:4.3.2:compile
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.5.2:compile
[INFO] | +- commons-logging:commons-logging:jar:1.2:compile
[INFO] | \- commons-codec:commons-codec:jar:1.9:compile
[INFO] +- com.sendgrid:smtpapi-java:jar:1.0.0:compile
[INFO] \- org.apache.httpcomponents:httpmime:jar:4.3.4:compile
Note:
We get org.apache.httpcomponents:httpclient:jar:4.5.2:compile
We also get org.apache.httpcomponents:httpcore:jar:4.3.2:compile
A potential versons mismatch happens here between libraries of the same family
Adding then to the module-a's pom.xml the following:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.2</version>
</dependency>
</dependencies>
</dependencyManagement>
And re-running our dependency tree execution, we get as part of the output:
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # module-a ---
[INFO] com.sample:module-a:jar:0.0.1-SNAPSHOT
[INFO] \- com.sendgrid:sendgrid-java:jar:2.0.0:compile
[INFO] +- org.json:json:jar:20140107:compile
[INFO] +- org.apache.httpcomponents:httpcore:jar:4.3.2:compile
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.3.2:compile
[INFO] | +- commons-logging:commons-logging:jar:1.1.3:compile
[INFO] | \- commons-codec:commons-codec:jar:1.6:compile
[INFO] +- com.sendgrid:smtpapi-java:jar:1.0.0:compile
[INFO] \- org.apache.httpcomponents:httpmime:jar:4.3.4:compile
We now get httpcore and httpclient aligned, with the versions we wanted.
Also note the httpmime to version 4.3.4, it's a fix version change, but still a misalignment (should be harmless though).
In this case it seems you are adding governance at parent level in dependencyManagement (good approach), but then at the level of one of the modules you need to override it. That can happen, but better to properly comment it, for maintenance and for the future yourself looking at it in the future.
Also note: other modules in this project would not be affected by this change, that is, they will still get version 4.5.2. If the final result of the whole multimodule build is an ear or war file, for example, carefully check what you eventually get.
It is impossible in a simple maven project to have 2 different versions of the same artifact in the classpath. So you cannot have 4.3.2 and 4.5.2 versions in the classpath simultaneously.
However there are several options... You can either
use in your project the older version (4.3.*), compatible with sendgrid-java dependency (simplest way); or
update sendgrid-java dependency, if newer one is compatible with http components 4.5.* (preferred way); or
mark sendgrid-java as a 'provided' dependency, build a separate class loader in runtime and load it with correct dependencies versions (a bit tricky, but I saw this approach in a couple bank applications)
An excerpt from my project's dependency tree:
myproject
+- qxwebdriver-java 0.0.3
+- operadriver 1.5
| +- guava 14.0
+- selenium-java 2.52.0
+- selenium-remote-driver 2.52.0
| +- guava
+- selenium-safari-driver 2.52.0
Guava is required two times, via operadriver and selenium-remote-driver. In the latter case, dependency is declared without version. The project itself requires qxwebdriver-java and nothing more.
In this configuration, Safari driver does not work:
java.lang.NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch;
at org.openqa.selenium.safari.SafariDriverCommandExecutor.start(SafariDriverCommandExecutor.java:111)
This happens because the project's overall dependency on Guava resolves to 14.0 (via operadriver). However the required Stopwatch::createStarted() method has been introduced in Guava 19.0. Manually adding Guava 19.0 dependency to the project's POM fixes the issue.
But isn't this an issue of Selenium and/or Opera driver packaging? Do you think it should be reported upstream, or is my workaround the right way to do things like this in Maven?
This is a perfectly common situation in Java and Maven, and not a defect.
The correct solution is to add an exclusion in your pom. Something like this:
<dependency>
<groupId>com.opera</groupId>
<artifactId>operadriver</artifactId>
<version>1.5</version>
<exclusions>
<!-- outdated library conflicts with selenium-java -->
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>[2.33.0,)</version>
<scope>test</scope>
</dependency>
Note that in rare cases - for example if guava version 19 deprecated something from version 14, that operadriver 1.5 depends on - doing this could break, in this case, operadriver.
I'm trying to mock a constructor using PowerMockito but every time I run the test I get the following error:
java.lang.NoSuchMethodError: org.mockito.internal.creation.MockSettingsImpl.setMockName(Lorg/mockito/mock/MockName;)Lorg/mockito/internal/creation/settings/CreationSettings;
at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:107)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:60)
at org.powermock.api.mockito.internal.expectation.DefaultConstructorExpectationSetup.createNewSubstituteMock(DefaultConstructorExpectationSetup.java:105)
at org.powermock.api.mockito.internal.expectation.DefaultConstructorExpectationSetup.withAnyArguments(DefaultConstructorExpectationSetup.java:71)
I have the following PowerMock dependencies in my project:
org.powermock:powermock-module-junit4:1.5.6
org.powermock:powermock-mockito-release-full:1.5.6
I've traced the dependency tree of my project and fixed conflicts so that mockito-all:1.9.5 gets included in the build.
Make sure powermockito and mockito versions are aligned as in this versions chart - MockitoUsage#supported-versions,
Mockito | PowerMock
------------------------------------------------------------------------------
2.0.0-beta - 2.0.42-beta | 1.6.5+
------------------------------------------------------------------------------
1.10.19 | 1.6.4
1.10.8 - 1.10.x | 1.6.2+
1.9.5-rc1 - 1.9.5 | 1.5.0 - 1.5.6
1.9.0-rc1 & 1.9.0 | 1.4.10 - 1.4.12
1.8.5 | 1.3.9 - 1.4.9
1.8.4 | 1.3.7 & 1.3.8
1.8.3 | 1.3.6
1.8.1 & 1.8.2 | 1.3.5
1.8 | 1.3
1.7 | 1.2.5
Easy way to find mockito and powermock-mockito version using maven is,
mvn dependency:tree | grep mockito
[INFO] | \- org.mockito:mockito-core:jar:1.8.5:compile
[INFO] +- org.mockito:mockito-all:jar:1.8.5:compile
[INFO] +- org.powermock:powermock-api-mockito:jar:1.4.9:compile
Problem could be the conflicting versions of mockito in the application and the one that powermockito uses, conflicting as below in my case where I'm using powermock 1.6.5 which does not support mockito 1.8.5
mvn clean dependency:tree | grep mockito
[INFO] +- org.mockito:mockito-all:jar:1.8.5:compile
[INFO] \- org.powermock:powermock-api-mockito:jar:1.6.5:compile
[INFO] +- org.mockito:mockito-core:jar:1.10.19:compile
[INFO] \- org.powermock:powermock-api-mockito-common:jar:1.6.5:compile
I had
org.mockito
mockito-all
1.8.4
added to my pom.xml apart from powermock's dependecies, removing this worked for me.
My problem was due to conflicting versions of javassist in my project's (transitive) dependencies. What I did was search for all dependencies that put old version of javassist in the build, then exclude them. For example:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.5.1-Final</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</exclusion>
</exclusions>
</dependency>
while migrating springboot from 1.5 to 2.0.7
The versions of mockito in springboot and powermock are different so explicitly give mockito dependency
This is compatible while migrating to springboot 2.0.7
testCompile "org.powermock:powermock-api-mockito2:${powermockVersion}"
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.8.9'
testCompile "org.powermock:powermock-module-junit4:1.7.3"
testCompile "org.powermock:powermock-core:1.7.3"
For me, in Eclipse, the fix to this problem was found in Java Build Path. Click on Order and Export tab. Move Web App Libraries to bottom. Note, that when appropriate, this will also allow you to view source of 3rd party libraries when Eclipse tells you that source cannot be found.
In my case it was a conflict dependency.
I had fix it after exclude mockito-core artifact:
<dependency>
<groupId>com.googlecode.catch-exception</groupId>
<artifactId>catch-exception</artifactId>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
<version>1.0.4</version>
<scope>test</scope>
</dependency>
Also, consider removing PowerMock, bytebuddy and objenesis dependencies at all. Keep only the following Mockito dependency.
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.7.12</version>
<scope>test</scope>
</dependency>
This should fix the error for the most part of the scenarios.
I'm having trouble including Google Play Services in a Maven build. I've use the android SDK deployer to deploy an apklib for GPS and have added the following to my pom.xml.
<dependency>
<groupId>com.google.android.gms</groupId>
<artifactId>google-play-services</artifactId>
<version>7</version>
<type>apklib</type>
</dependency>
<dependency>
<groupId>com.google.android.gms</groupId>
<artifactId>google-play-services</artifactId>
<type>jar</type>
<version>7</version>
</dependency>
This works for importing the library but the issue occurs when I try to build the project using Maven. I get the following error during the build process.
[INFO] UNEXPECTED TOP-LEVEL EXCEPTION:
[INFO] java.lang.IllegalArgumentException: already added: Landroid/UnusedStub;
[INFO] at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:123)
[INFO] at com.android.dx.dex.file.DexFile.add(DexFile.java:163)
[INFO] at com.android.dx.command.dexer.Main.processClass(Main.java:490)
[INFO] at com.android.dx.command.dexer.Main.processFileBytes(Main.java:459)
[INFO] at com.android.dx.command.dexer.Main.access$400(Main.java:67)
[INFO] at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:398)
[INFO] at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:245)
[INFO] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:131)
[INFO] at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:109)
[INFO] at com.android.dx.command.dexer.Main.processOne(Main.java:422)
[INFO] at com.android.dx.command.dexer.Main.processAllFiles(Main.java:333)
[INFO] at com.android.dx.command.dexer.Main.run(Main.java:209)
[INFO] at com.android.dx.command.dexer.Main.main(Main.java:174)
[INFO] at com.android.dx.command.Main.main(Main.java:91)
I've been able to resolve the error by setting the scope on the jar or apklib to provided but this causes a class not found exception at runtime. What am I missing here? From everything I've read online this is all you should need to use GPS with Maven.
It turns out another dependency of mine was also pulling down Google Play Services. I'm using the Drive SDK in my application along with google-api-client-android which was the culprit. The frustrating part was that the groupId and artifactId for GPS was different in google-api-client-android than the ones generated using the Android SDK Deployer. The solution was to add the exclusion to the google-api-client-android dependency as follows.
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client-android</artifactId>
<version>1.15.0-rc</version>
<exclusions>
<exclusion>
<groupId>com.google.android.google-play-services</groupId>
<artifactId>google-play-services</artifactId>
</exclusion>
</exclusions>
</dependency>