I am having com.squareup.okhttp3:okhttp-urlconnection:3.13.1 jar as dependency in gradle file of my Android project and used as below to get the URLConnection.
protected URLConnection getStandardHTTPURLConnection(URL url) throws IOException {
return new OkHttpURLConnection(url, builder.cookieJar(new JavaNetCookieJar(CookieHandler.getDefault())).build());
}
So I updated the jar to 4.9.0 and realized that OkHttpURLConnection is not available. It is leading to noClassDefinition exception in the run time. so what are the alternatives? Is it deprecated or moved under another hood?
Below are my imports.
import okhttp3.internal.huc.OkHttpURLConnection;
import okhttp3.internal.huc.OkHttpsURLConnection;
Kindly advice.
There's a compatibility implementation you can paste in that's mentioned in the OkHttp 3.14.0 release notes.
https://square.github.io/okhttp/changelog_3x/#version-3140
From https://square.github.io/okhttp/changelog_3x/ so I guess they got removed on 4.x
The Apache HTTP client and HttpURLConnection APIs are deprecated. They
continue to work as they always have, but we’re moving everything to
the new OkHttp 3 API. The okhttp-apache and okhttp-urlconnection
modules should be only be used to accelerate a transition to OkHttp’s
request/response API. These deprecated modules will be dropped in an
upcoming OkHttp 3.x release.
Related
I'm trying to build a testing framework for an android application using selenium webdriver on eclipse and Appium. I'm not using Maven. The initial script to launch the app is as follows:
package executionEngine;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import io.appium.java_client.android.AndroidDriver;
public class DriverScript {
public static AndroidDriver driver = null;
public static void main(String[] args) throws MalformedURLException {
// TODO Auto-generated method stub
File app = new File(System.getProperty("user.dir")+"\\BP_QASTG.apk");
// Created object of DesiredCapabilities class.
DesiredCapabilities capabilities = new DesiredCapabilities();
//capabilities.setCapability(CapabilityType.BROWSER_NAME,"");
// Set android deviceName desired capability. Set your device name.
capabilities.setCapability("deviceName", "Galaxy Tab A");
// Set android VERSION desired capability. Set your mobile device's OS version.
capabilities.setCapability(CapabilityType.VERSION, "6.0.2");
// Set android platformName desired capability. It's Android in our case here.
capabilities.setCapability("platformName", "Android");
// Set android appPackage desired capability. It is
capabilities.setCapability("appPackage", "com.rivigo.zoombp.rivigozoombpapp");
// Set android appActivity desired capability. It is
capabilities.setCapability("appActivity", "com.rivigo.zoombp.rivigozoombpapp.activity.Activity.RivigoHomeActivity");
capabilities.setCapability("app", app.getAbsolutePath());
// Set appium server address and port number in URL string.
//AndroidDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
//driver = (AndroidDriver)((new URL("http://127.0.0.1:4723/wd/hub"), capabilities));
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
}
}
In the above code, the line where I declare the URL is marked in RED and hovering over it shows me this message: "The type org.openqa.selenium.remote.http.HttpClient$Factory cannot be resolved. It is indirectly referenced from required .class files"
I have seen many answers asking to add required jar files; but I'm sure I have added all the jar files required. It would be great if anyone can point out the particular jar file I might have missed,if indeed that is the issue, so that I can download and add it separately.
I have seen other answers asking to remove and re-add the JRE system library or close and repair the project, etc. which did not work for me.
I have tried with eclipse-neon and eclipse-mars versions also.
Please ask for any details you need,
I'm blocked here for quite sometime,
help on this would be appreciated,
Thanks,
Rahul
I encountered similar exception while working on automation framework which was built to serve as a base framework for UI (Mobile and Web) and AIP automation. Technologies which I was using included selenium web driver and appium for UI and Mobile automation. This was maven project and I ended up having bunch of dependencies. When I spent a hell lot time investigating my exceptions, root cause I found was dependency conflict because there were lot of dependencies which included different version of same artifact. In this case dependency in conflict was "com.squareup.okhttp3" which i had defined explicitly in my POM and same dependency is part of selenium-java as well. Please try following solution and hopefully that should work:
Exception:
Exception in thread "main" java.lang.NoClassDefFoundError: okhttp3/ConnectionPool
at org.openqa.selenium.remote.internal.OkHttpClient$Factory.<init>(OkHttpClient.java:116)
at org.openqa.selenium.remote.http.HttpClient$Factory.createDefault(HttpClient.java:66)
at org.openqa.selenium.remote.HttpCommandExecutor.<clinit>(HttpCommandExecutor.java:47)
at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:95)
at io.appium.java_client.android.AndroidDriver.<init>(AndroidDriver.java:94)
at nz.co.flexicards.automation.framework.common.Common.BaseMobile.main(BaseMobile.java:62)
Caused by: java.lang.ClassNotFoundException: okhttp3.ConnectionPool
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 6 more
Process finished with exit code 1
Solution:
I removed the explicit dependency for okhttp3 from POM.xml
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
<scope>test</scope>
</dependency>
Moved java-client (appium-io) dependency on top in dependency list in POM.xml
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>7.2.0</version>
</dependency>
try the below code before creating the driver object.
System.setProperty("webdriver.http.factory", "apache");
This requires
commons-validator.jar
which has set of methods to do common http and other user requests and validations.
And kindly update your selenium jar as 2.5x or more have come now
The problem got solved when I followed below steps,
Created a new project
Added Selenium (2.53.1), gson (2.2.4-sources) and javaclient(4.0.0) jars
Previously I added different version of java client jar; I did not add any gson jar before.
Maybe these changes solved my problem. (I'm not sure though)
Regards,
Rahul
This problem occured today.
I just switched the version of java-client from 5.0.0 to 1.2.1, and found the problem solved.
Hope this would be helpful.
Add the below maven dependency to your pom.xml to resolve the issue.
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-remote-driver</artifactId>
<version>3.4.0</version>
</dependency>
It might have problem with java-client jar.
After changing java-client-7.0.0 version to java-client-3.2.0 my problem is solved.
I removed all the externals libraries that I had, and then I add java-client/7.0.0.
It has anything that you need, then my project worked.
https://jar-download.com/artifacts/io.appium/java-client/7.0.0/source-code
Adding "selenium-remote-driver" solved the problem
appium , selenium, okhttp alltogether happily, please check my answer :
Appium throws an error because of the driver
We know that Android M has removed support for HttpClient. Apps linking with it will have to explicitly say so: add a library dependency in your gradle file.
But does it break backward compatibility with existing applications?
Suppose I wrote an app which supports Api level 1 and higher and it's never maintained since last year. The targetSdkLevel of the app is certainly lower than 22. Will it crash on Android M? The source code could have been lost.
The answer looks to be yes.
I looked in the Android M source code through the SDK manager, and the package for the client is not in the source.
Package name for the HttpClient:
org.apache.http.client.HttpClient
Existing paths:
org.apache.http.conn
org.apache.http.params
Ways to fix this:
Add this to your build.graddle:
android {
useLibrary 'org.apache.http.legacy'
}
Use OkHttp-UrlConnection as an almost drop in replacement by adding this to your build.graddle:
compile 'com.squareup.okhttp:okhttp-urlconnection:2.4.0'
Example usage:
private static OkHttpClient okHttpClient = new OkHttpClient();
HttpURLConnection urlConnection = new OkUrlFactory(okHttpClient).open(url);
I'm testing Volley's HurlStack in Android M Developer Preview.
After I change compileSdkVersion from 22 to 'android-MNC', all classes from org.apache.http are not compiled:
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.StatusLine;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;
How can I modify my code to solve this problem?
I know there're some changes related to Apache HTTP client, but it still doesn't work when I follow the steps to add useLibrary 'org.apache.http.legacy' in gradle.
Reference: HurlStack.java AOSP
Behavior Changes: Apache HTTP Client Removal
The official “Behaviour Changes” document states that the Apache HTTP client is removed in Android M — not deprecated, but removed. Personally I highly suggest switching to OkHttp which actually is used as a HttpURLConnection engine since KitKat, by using a dependency you get all fresh goodies from Square team directly.
You can ignore these warns, because Volley is still compiled using API 22:
https://github.com/mcxiaoke/android-volley/blob/master/gradle.properties
add these in proguard configuration:
-dontwarn org.apache.http.**
-dontwarn com.android.volley.toolbox.**
Apart from using okHttp, the fallback is to use legacy apache httpclient as suggested by Google.
See my answer here to get it working.
How to use the legacy Apache HTTP client on Android Marshmallow?
If, like me, the only reason you were including HttpClient is because you were testing HTTP response codes:
if (error.networkResponse.statusCode == HttpStatus.SC_UNAUTHORIZED) {}
then a simple fix is just to use the version of the constants that are in the HttpURLConnection class:
if (error.networkResponse.statusCode == HttpURLConnection.HTTP_UNAUTHORIZED) {}
While following the steps outlined here :
https://cloud.google.com/developers/articles/how-to-build-mobile-app-with-app-engine-backend-tutorial/
for creating a cloud endpoint, but using Android Studio instead of Eclipse, I am stuck at Step 9 of the Entity Class Design Pattern as described here :
https://cloud.google.com/developers/articles/how-to-build-mobile-app-with-app-engine-backend-tutorial/#ecdp
In Eclipse, there is a right-click-menu-option for "Generate Cloud Endpoint Client library" when you right-click on the app engine project. However, there is no equivalent option in Android Studio (v1.0.0)
Is this an omission on Google's part or am I missing something.
What is the best workaround for generating the cloud endpoint client library from within Android Studio.
Is there a way to do it from the command-line?
I did find the steps for gradle here :
https://cloud.google.com/appengine/docs/java/endpoints/endpoints_tool
and here :
https://cloud.google.com/appengine/docs/java/endpoints/consume_android
but these are much more time-consuming than the single-step process described in the original link for eclipse.
As stated above the libraries are auto-compiled for you, the other point to note that had me confused is where to get the Builder from.
Now as of Android Studio 1.0.1 the original Eclipse instructions are a little out of date for this as well, the "Builder" is no longer buried into the Endpoint class you make. Instead it is rolled into a separate API class to describe the Builder and associated code.
See: https://github.com/GoogleCloudPlatform/gradle-appengine-templates/tree/master/HelloEndpoints
Endpoint Usage from Android would now look like this:
/* OLD
MyEndpoint.Builder builder = ... */
MyApi.Builder builder = new MyApi.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// options for running against local devappserver
// - 10.0.2.2 is localhost's IP address in Android emulator
// - turn off compression when running against local devappserver
.setRootUrl("http://10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
#Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
});
We're working on updating that shopping kart sample to use Android Studio.
In the meantime the documentation for generating endpoints in AS can be found here https://cloud.google.com/tools/android-studio/
There is no 'Generate Cloud Endpoint Client Library' task anymore since it's not needed in the Android Studio workflow. Simply building the project will ensure that the client libraries are available to your android app.
Check out the docs for the appengine gradle plugin https://github.com/GoogleCloudPlatform/gradle-appengine-plugin if you want to be able to manually perform some of the endpoint client library steps from the command line using Gradle.
As Lucien Murray-Pitts explained, the Builder is not in the Endpoint class but in a auto-generated XXXXApi class.
Imagine your java bean is a class called Portfolio under package com.example.backend
You have to add the following import in the AsyncTask class:
import com.example.backend.portfolioApi.PortfolioApi;
and then you can do
PortfolioApi.Builder builder = new PortfolioApi.Builder(....
I am builting a library which has android and server versions.
The LdapJDK imports javax.naming classes which are not included in android JDK.
Since LdapJDK wouldn't be called on android version of my library, below code works on android phone.
But I am not sure this is a safe way. If some application(eg: webserver) checks all the classes dependency during initialization, my library would cause exceptions.
I would appreciate any comments.
public static X509Certificate[] getCertFromLDAP(String url, String dn) throws ASN1Exception, CertificateException, UnsupportedEncodingException
{
if (JeTS.getType() == PKIConstants.ANDROID_TYPE)
return LdapAndroid.getCertFromLDAP(url, dn);
else
return LdapJDK.getCertFromLDAP(url, dn);
}
If you want to be safe, create different jars for Android and your server. Exclude anything you don't need/can't use from the Android one.
With that said, as long as you are running on Android 2.x and later, classes are lazy loaded and the code above won't be a problem. Android uses the same pattern to handle backward compatibility, so this is tried and tested.