Verifier rejected class software.amazon.awssdk.http.apache.ApacheHttpClient - android

I'm trying to run the code that I copy-pasted from here, specifically this line
val region = Region.AP_SOUTHEAST_1
val s3 = S3Client.builder().region(region).build()
but everytime I run it, it will give me this error
java.lang.VerifyError: Verifier rejected class
software.amazon.awssdk.http.apache.ApacheHttpClient: void
software.amazon.awssdk.http.apache.ApacheHttpClient.lambda$LRMaF_8eLuzzpRjS-Ew4gJswCBw(org.apache.http.client.methods.HttpRequestBase) failed to verify: void
software.amazon.awssdk.http.apache.ApacheHttpClient.lambda$LRMaF_8eLuzzpRjS-Ew4gJswCBw(org.apache.http.client.methods.HttpRequestBase):
[0x0] 'this' argument 'Reference:
org.apache.http.client.methods.HttpRequestBase' not instance of
'Reference:
org.apache.http.client.methods.AbstractExecutionAwareRequest'
(declaration of 'software.amazon.awssdk.http.apache.ApacheHttpClient'
appears in
/data/app/com.imincode.earthlings-Jxs426ZYpcjwZtg1zzKjkw==/base.apk!classes3.dex)
at software.amazon.awssdk.http.apache.ApacheHttpClient.builder(ApacheHttpClient.java:133)
at software.amazon.awssdk.http.apache.ApacheSdkHttpService.createHttpClientBuilder(ApacheSdkHttpService.java:29)
at software.amazon.awssdk.core.internal.http.loader.-$$Lambda$-cEpDqlhpsSVBRGa6lPjzgTy1tM.apply(Unknown
Source:2)
at java.util.Optional.map(Optional.java:211)
at software.amazon.awssdk.core.internal.http.loader.DefaultSdkHttpClientBuilder.buildWithDefaults(DefaultSdkHttpClientBuilder.java:41)
at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.lambda$resolveSyncHttpClient$5$SdkDefaultClientBuilder(SdkDefaultClientBuilder.java:274)
at software.amazon.awssdk.core.client.builder.-$$Lambda$SdkDefaultClientBuilder$mSpkyGAugx5W7tgD88eQuJnqvEs.get(Unknown
Source:2)
at java.util.Optional.orElseGet(Optional.java:263)
at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.resolveSyncHttpClient(SdkDefaultClientBuilder.java:274)
at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.finalizeSyncConfiguration(SdkDefaultClientBuilder.java:225)
at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.syncClientConfiguration(SdkDefaultClientBuilder.java:158)
at software.amazon.awssdk.services.s3.DefaultS3ClientBuilder.buildClient(DefaultS3ClientBuilder.java:27)
at software.amazon.awssdk.services.s3.DefaultS3ClientBuilder.buildClient(DefaultS3ClientBuilder.java:22)
at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.build(SdkDefaultClientBuilder.java:129)

I got the same error working with timestream db. So in my case, timestreamWriteClient accepts ApacheHttpClient.Builder:
ApacheHttpClient.Builder httpClientBuilder =
ApacheHttpClient.builder();
return TimestreamWriteClient.builder()
.httpClientBuilder(httpClientBuilder)
.overrideConfiguration(overrideConfig.build())
.region(Region.US_EAST_1)
.build();
And on runtime, when app tries to create apache client, I got this error. So during some investigations, I found, that I can use another HTTP client - UrlConnectionHttpClient and pass it to TimestreamWriteClient.Builder.
httpClientBuilder: UrlConnectionHttpClient.Builder = UrlConnectionHttpClient.builder()
But this client should be included separately:
implementation 'software.amazon.awssdk:url-connection-client'
You can add version, adding ":X.Y.Z" at the end, but I use BOM, so I don't know anything about versions:
implementation platform('software.amazon.awssdk:bom:2.15.0')
So, I think, that you also can pass this HTTP client to your S3 service builder, like I'm doing this with timestreamWriteClient builder.

Related

Microsofts java implementation of MSAL ISingleAccountPublicClientApplication.acquireTokenSilent is deprecated, new method gives 401 unauthorized error

MSALs java methods of ISingleAccountPublicClientApplication
signIn(activity, loginHint, scopes, authenticationCallback) and acquireTokenSilent(scopes, authority) is deprecated, in favour of build methods.
So I changed the signIn to use SignInParameters.builder() like this:
(below in kotlin)
From:
...signIn(
signInActivity,
null, //loginHint
arrayOf(accessScope),
object : AuthenticationCallback { /*omitted*/ },
)
To:
...signIn(
SignInParameters.builder(
.withActivity(signInActivity),
.withScopes(arrayOf(accessScope).toMutableList())
.withCallback(
object : AuthenticationCallback { /*omitted*/
})
.build()
)
So far, the sign in process seems to go well, no errors, but the problems occures when I call the new acquireTokenSilent method with AcquireTokenSilentParameters used.
From:
val iAuthenticationResult = singleAccountApp.acquireTokenSilent(
arrayOf(accessScope),
MICROSOFT_ACCESS_AUTHORITY
)
To:
val iAuthenticationResult = singleAccountApp.acquireTokenSilent(
AcquireTokenSilentParameters(
AcquireTokenSilentParameters.Builder()
.withScopes(arrayOf(accessScope).toMutableList())
.fromAuthority(MICROSOFT_ACCESS_AUTHORITY)
)
)
Now I get following error message in response when acquiring token:
The signed in account does not match the provided account which further causes 401 Unauthorized response.
Rewinding back to use the old method just for acquireTokenSilent does not produce any error and the token is provided.
Now I am stuck in new for signIn method, but an old one for the acquireTokenSilent method.
Is there anything I have skipped or forgotten using the newer one ?

AWS Android initialization error | how to initialize

Getting error when trying to update version
https://search.maven.org/artifact/com.amazonaws/aws-android-sdk-auth-userpools
val initializeBuilder = AWSMobileClient.getInstance().initialize(activity) {
createAwsSessionComponent(environment, configuration)
doAfter.run()
}
initializeBuilder.awsConfiguration(configuration)
initializeBuilder.execute()
getting error
Type mismatch.
Required:
Callback<UserStateDetails!>!
Found:
() → Unit
I am currently getting this error while logging analytics was able to log all other events but a specific event when popup box is display i am getting this issue.
AbstractKinesisRecorder: DeadLetterListener onRecordsDropped has thrown an exception (user code)
java.lang.NullPointerException: Attempt to invoke interface method 'void com.amazonaws.mobileconnectors.kinesis.kinesisrecorder.DeadLetterListener.onRecordsDropped(java.lang.String, java.util.List)' on a null object reference
AbstractKinesisRecorder: ServiceException in submit all, the last request is presumed to be the cause and will be dropped
com.amazonaws.AmazonServiceException: User:
To create a Native Android Mobile app that can invoke AWS Services, try using the AWS SDK for Kotlin. You can find information on how to get up and running with this SDK here:
Setting up the AWS SDK for Kotlin
This SDK works nicely with Android Studio to build Android Apps. It exposes a strongly typed Service Client you can use within an Android Studio project. For example, to invoke SNS, you can use SnsClient:
fun getClient() : SnsClient{
val staticCredentials = StaticCredentialsProvider {
accessKeyId = "<Enter key>"
secretAccessKey = "<Enter key>"
}
val snsClient = SnsClient{
region = "us-west-2"
credentialsProvider = staticCredentials
}
return snsClient
}
Link in the comment below.

OkHttp 4.x giving error when trying to access url via Call request

I recently started update to okhttp3 to 4.x
In doing so I am getting following build time error:
Using 'url(): HttpUrl' is an error. moved to val
The issue is happening when I am trying to get url from request object obtained via call:
e.g
call.enque(callback : Callback){
override fun onFailure(call : Call, t:Throwable) {
val url = call.request().url().toString
}
}
I looked up further and the Url object within Request is val aka final now.
Also, no directions on their upgrade guide https://square.github.io/okhttp/upgrading_to_okhttp_4/
I would appreciate for any suggestions on another way to obtain Url.
Using 'url(): HttpUrl' is an error. moved to val
This means you should change the function call url() to a property access url.
okhttp 4 comes with replaceWith param in the deprecation annotation that makes e.g. Android Studio to offer that fix automatically with right-click/alt-enter on the error:
#Deprecated(
message = "moved to val",
replaceWith = ReplaceWith(expression = "url"),
level = DeprecationLevel.ERROR)
From comments:
Upon further investigation I found out that the request() or Request object is from Retrofit 2. And Retrofit 2 returns call object from okhttp3
That's an issue with Android Studio. You can work around it with explicit cast to okhttp 4 types, e.g. (call.request() as Request).url.
In my case, I just had to remove the brackets:
call.request().url() -> call.request().url

Android switch from Parse to Parse Server crashes

I'm migrating my Android and iOS app from Parse.com to Parse Server. First I'm doing this migration with a test app to be sure everything is ok.
With iOS there has been no problem but with Android the updated app crashes each time the user enters in the app.
This is the Android code updated:
public static void initParse(Application app) {
ctxt = app.getApplicationContext();
Parse.enableLocalDatastore(app);
// Old version
//Parse.initialize(app, "<my app id>", "<my client key>");
// New version
Parse.initialize(new Parse.Configuration.Builder(ctxt)
.applicationId("<my app id>")
.clientKey(null)
.server("https://<my new server>/parse/")
.build()
);
ParseUser.enableRevocableSessionInBackground();
}
The crash returns a "com.parse.ParseException: java.lang.IllegalStateException: unable to encode an association with an unsaved ParseObject", and taking into account what I've read in Stackoverflow, this is because ParseUser.getCurrentUser() returns null (despite the user is logged in) and Parse methods fail.
In fact, if I take this same code, uncomment the old version of Parse.initialize, comment the new version of Parse.initialize, compile and launch the app, this is launched without problems and the user can use it properly.
But again, if I comment the old version of Parse.initialize, uncomment the new version of Parse.initialize, compile and launch the app, this crashes inmediately because ParseUser.getCurrentUser() returns null and Parse methods fail.
What am I missing here? Should I force my users to login again? This seems to me a bad UX, and anyway, in iOS I have no problems with the new version, what is the difference between both platforms?
EDIT 1:
Following Robert Rowntree advice I've changed the initialization to this:
public static void initParse(Application app) {
ctxt = app.getApplicationContext();
Parse.enableLocalDatastore(app);
// Old version
//Parse.initialize(app, "<my app id>", "<my client key>");
// New version
Parse.initialize(new Parse.Configuration.Builder(ctxt)
.applicationId("<my app id>")
.clientKey("<my client key>")
.server("https://<my new server>/parse/")
.build()
);
//Parse.setLogLevel(Parse.LOG_LEVEL_DEBUG);
Parse.setLogLevel(Parse.LOG_LEVEL_VERBOSE);
ParseUser.enableRevocableSessionInBackground();
}
Besides this I've checked that my Parse version is the last available, I have this in my gradle file:
compile 'com.parse.bolts:bolts-android:1.+'
compile 'com.parse:parse-android:1.+'
And the result is the same, the app crashes with "com.parse.ParseException: java.lang.IllegalStateException: unable to encode an association with an unsaved ParseObject" the first call I make to Parse.
Besides this, the unique log I can see related to parse is one related to GCM token, nothing else.
EDIT 2:
I've tried another thing, uninstall the app with the old initialization and install it with the new initialization and as I guessed the new version is now working.
But, of course this is not a solution to me, I can not tell my users to uninstall the app ans install it again.
But this is a hint: there is no problem with the new initialization but with how the old Parse "reacts" when opening the app with the new Parse Server, there must be any inconsistency in getCurrentUser or something like that.
Can you try initializing like this:
Parse.initialize(new Parse.Configuration.Builder(this)
.applicationId("APP_ID")
.clientKey("CLIENT_KEY")
.server("https://SERVER_URL/parse/") // The trailing slash is important.
.enableLocalDataStore()
.build()
);
notice the
.enableLocalDataStore()
is in the initilization. Remove this:
Parse.enableLocalDatastore(app);

RequestFactory fails with "UnexpectedException: No RequestContext for operation LPZEK7DlYkoG1$NQ5MjHlmuRChk="

Could you guys please help me why I'm having this exception?
I extracted RequestFactory proxies and context interfaces into separate jar so I can use it both in GWT client and Android client (details are here)
Unfortunately RF throws an exception on the server in very first call. The exception is:
com.google.web.bindery.requestfactory.server.UnexpectedException: No RequestContext for operation LPZEK7DlYkoG1$NQ5MjHlmuRChk=
at com.google.web.bindery.requestfactory.server.ServiceLayerDecorator.die(ServiceLayerDecorator.java:216)
at com.google.web.bindery.requestfactory.server.ResolverServiceLayer.resolveRequestContext(ResolverServiceLayer.java:154)
Below is my factory interface. As you can see I had to replace Service annotations with ServiceName because I didn't want to compile all custom locators with Guice injections to jar that will go on mobile devices.
public interface AdminRequestFactory extends RequestFactory
{
// #Service(value = UserServiceDao.class, locator = InjectingServiceLocator.class)
#ServiceName(value = "com.blah.courierApp.server.dao.UserServiceDao", locator = "com.blah.courierApp.server.inject.InjectingServiceLocator")
public interface GaeUserServiceContext extends RequestContext
{
public Request<String> createLogoutURL(String destinationURL);
public Request<GaeUser> getCurrentUser();
}
// #Service(value = OrderDao.class, locator = InjectingServiceLocator.class)
#ServiceName(value = "com.blah.courierApp.server.dao.OrderDao", locator = "com.blah.courierApp.server.inject.InjectingServiceLocator")
public interface OrderRequestContext extends RequestContext
{
Request<List<OrderProxy>> listAll();
Request<Void> delete(Long id);
Request<Void> createOrder(OrderProxy order);
Request<OrderProxy> findOrderById(long id);
Request<Void> updateOrderState(long id, StateType newStateType);
}
GaeUserServiceContext contextUserService();
OrderRequestContext contextOrder();
}
When I compiled it RF Annotation Tool gave following warning:
Cannot fully validate context since domain type com.blah.courierApp.server.dao.UserServiceDao is not available.
You must run the ValidationTool as part of your server build process.
Add #SuppressWarnings("requestfactory") to dismiss.
So when the exception thrown under the debugger on the server I see that instance of com.google.web.bindery.requestfactory.vm.impl.Deobfuscator has empty operationData field which is being initialized by DeobfuscatorBuilder class that was generated by RequestFactory annotation tool.
So... I decompiled that class and found this:
public final class AdminRequestFactoryDeobfuscatorBuilder extends Deobfuscator.Builder
{
public AdminRequestFactoryDeobfuscatorBuilder()
{
withRawTypeToken("w1Qg$YHpDaNcHrR5HZ$23y518nA=", "com.google.web.bindery.requestfactory.shared.EntityProxy");
withRawTypeToken("8KVVbwaaAtl6KgQNlOTsLCp9TIU=", "com.google.web.bindery.requestfactory.shared.ValueProxy");
withRawTypeToken("FXHD5YU0TiUl3uBaepdkYaowx9k=", "com.google.web.bindery.requestfactory.shared.BaseProxy");
withRawTypeToken("5vjE9LUy$l0uvi4kMYpS3JA1WEE=", "com.blah.shared.model.GaeUser");
withRawTypeToken("8KVVbwaaAtl6KgQNlOTsLCp9TIU=", "com.google.web.bindery.requestfactory.shared.ValueProxy");
withRawTypeToken("5a7OV4PSV$1xemsooKLfEQ4g5yY=", "com.blah.shared.proxies.OrderProxy");
withRawTypeToken("neR_xIhE5oZsc0HbnkAMa8A88yw=", "com.blah.shared.proxies.OrderStateProxy");
withRawTypeToken("t6gMQWDROJnYvqYhNURV8pd$sn4=", "com.blah.shared.proxies.OrganizationProxy");
withRawTypeToken("1o45xgS$5bIkBKF4wlR8oMw_FSo=", "com.blah.shared.proxies.PersonProxy");
withRawTypeToken("FXHD5YU0TiUl3uBaepdkYaowx9k=", "com.google.web.bindery.requestfactory.shared.BaseProxy");
}
}
It didn't generated tokens for factory. Therefore there are no calls to Deobfuscator.Builder.withOperation because of which my server can't find context when calls comes from the client.
Questions are:
Why doesn't RequestFactory Annotation Tool generate tokens for factory (operations) ?
How can I fix it ?
Well, it was pretty tricky... But debugging in RF Annotation Tool helped :)
Turns out you have to have domain classes that you refer to in #ServiceName in classpath of RF Annotation Processor. It creates chicken-and-egg problem. You have to compile SharedClasses module to compile main module but you have to compile domain classes from main module to compile SharedClasses module.
Here is what I did:
Disabled RF annotation processing for SharedClasses module.
In RF annotation processor of main module I explicitly specified RF factory that has to be processed using parameter rootOverride = com.blah.shared.factories.AdminRequestFactory
It sucks that I have hardcoded full qualified class name in project settings though.
If you guys know more elegant method please let me know.
I too hit the same problem. Basically I have 3 GWT modules 1. Main module and in the second module I have the requestFactory, server domain classes and the client side proxy values. I am pretty much sure that your solution is what I need to put in place. However I am confused how to specify the rootOverride in the maven build phase. Any pointers in the structure of pom.xml would be immensely helpful.

Categories

Resources