java.lang.IllegalAccessError after migration from build 2011 to 2033

IDE: Fire
Version: 8.4.96.2033
Target (If relevant): Android
Description:
Only the following line will result in a bit weird runtime exception:
java.lang.IllegalAccessError: tried to access method geobingancore.android.CachedTileManager.set_pendingTasks:()V from class geobingancore.android.CachedTileManager$3

self._pendingTasks = Array<(TileID, (MapSegment?, Error?) -> Void)>(sequence: (self._pendingTasks.filter { $0.0 != tileID }))

from:

public func removeAllFetchingTask(forTileWithTileID tileID: TileID){
		
	synchronized(onLock: self.pendingTasksLock){
		#if COOPER

		self._pendingTasks = Array<(TileID, (MapSegment?, Error?) -> Void)>(sequence: (self._pendingTasks.filter { $0.0 != tileID }))

		#else
				
		var filteredAway = 0
		self._pendingTasks = self._pendingTasks.filter { (element) in
			let res = element.0 != tileID
			if !res {
				filteredAway += 1
			}
				
			return res
		}
				
			if filteredAway > 0 {
				print("Removed \(filteredAway) tiles from fetching")
			}
			
		#endif
	}
}

where pending tasks are defined in the same class as:

public var _pendingTasks = Array<(TileID, (MapSegment?, Error?) -> Void)>()

For some reason in build 2011 of the toolchain it works totally fine.

hrmm that is very odd. Do you have a more complete testcase I can try?

@ck: Sure, Let me try factoring out this piece that will reproduce this.

@ck:
So It came out to be I got a bunch of the similar messages across the project.
And now it seems it actually has to do with actual modifiers.
Here is the clarification:

Conditions to trigger such error:

  1. You have a class the contains the private variable (say base64AuthString).
  2. You have a method that will invoke another method that will execute asynch and as I result with set this private variable in its completionHandler.

So here is such a method:

public func performLogin(withUsername username: String, password: String, completionHandler: (Error?) -> Void)  {
		
	guard let base64String = String.base64CredentialString(withUsername: username, andPassword: password) else {
		let encodingError = ErrorBuilder.from(errorDescription: "General encoding error")
		completionHandler(encodingError)
		return
	}
	guard let userDetailURL = try? URL.constructWithValidation(fromString: apiURLBaseString + "user/details") else {
		let encodingError = ErrorBuilder.from(errorDescription: "General encoding error")
		completionHandler(encodingError)
		return
	}
		
	HTTPClient(basicAuthentificationString: base64String).performRequest(withURL: userDetailURL) { (responseº: Response?, dataº: Data?, errorº: Error?) in
			
		if let error = errorº   {
			completionHandler(error)
			return
		}
			
		guard let _ = responseº else   {
			let returnedError = ErrorBuilder.from(errorDescription: "Response missing")
			completionHandler(returnedError)
			return
		}
			
		guard let data = dataº else {
			let returnedError = ErrorBuilder.from(errorDescription: "No data in response")
			completionHandler(returnedError)
			return
		}
			
		if (data.toUTF8EncodedString() == "Couldn't authenticate you"){
			let returnedError = ErrorBuilder.from(errorDescription: "General login error")
			completionHandler(returnedError)
			return
		}
			
		self.base64AuthString = base64String
			
		#if COOPER
		if let context = self._context {
			let persistentPropertyList = PersistentPropertyList(applicationContext: context, preferenceFileKey: gLiteral.sharedPreferenceFileKey)
			persistentPropertyList.setString(base64String, forKey: self.peristentPropertyListTokenKey)
			persistentPropertyList.setString(username, forKey: self.persistentPropertyListTokenUsername)
			persistentPropertyList.synchronize()
		}
		#else
		let persistentPropertyList = PersistentPropertyList()
		persistentPropertyList.setString(base64String, forKey: self.peristentPropertyListTokenKey)
		persistentPropertyList.setString(username, forKey: self.persistentPropertyListTokenUsername)
		persistentPropertyList.synchronize()
		#endif
			
		completionHandler(nil)
	}
		
}

The problem appears in the generated binary as a result of how the following thing will be digested by the toolchain:

Looking at the decompiled .jar code:
The completionHandler now becomes a nameless class (NamelessClass_13), where original callee of performLogin (OSMAPIManager) will be stored as an ivar.
However as you can see later:
self.$self.setbase64AuthString(var8 = (String)self.base64String); will be called, but this generated setter is private, so IllegalAccessError will occur.

Changing the access modifier from private to public will resolve this issue.

Reference:

public class OSMAPIManager {

        //....

        private void setbase64AuthString(String value) {
            if(value == null) {
                throw new IllegalArgumentException("value");
            } else {
                self.$p_base64AuthString = value;
            }
        }
}

private final class NamelessClass_13 {
        public Action1<Exception> completionHandler;
        public OSMAPIManager $self;
        public String base64String;
        public String username;

        public NamelessClass_13() {
        }

        public void $performLogin$b__0(Response responseº, ByteBuffer dataº, Exception errorº) {
            Object error = null;
            if(errorº != null) {
                self.completionHandler.run(errorº);
            } else {
                Object anon$85 = null;
                Exception returnedError;
                if(responseº == null) {
                    returnedError = ErrorBuilder.from__errorDescription("Response missing");
                    self.completionHandler.run(returnedError);
                } else {
                    Object data = null;
                    if(dataº == null) {
                        returnedError = ErrorBuilder.from__errorDescription("No data in response");
                        self.completionHandler.run(returnedError);
                    } else {
                        String var10000 = __Extension_Data.toUTF8EncodedString(dataº);
                        if(var10000 == null?false:var10000.equals("Couldn\'t authenticate you")) {
                            returnedError = ErrorBuilder.from__errorDescription("General login error");
                            self.completionHandler.run(returnedError);
                        } else {
                            String var8;
                            self.$self.setbase64AuthString(var8 = (String)self.base64String);
                            Context context = null;
                            context = self.$self.access$0get_context();
                            if(context != null) {
                                PersistentPropertyList persistentPropertyList = new PersistentPropertyList(context, "geoBingAnCorePreference");
                                persistentPropertyList.setString____forKey(self.base64String, self.$self.$p_peristentPropertyListTokenKey);
                                persistentPropertyList.setString____forKey(self.username, self.$self.$p_persistentPropertyListTokenUsername);
                                persistentPropertyList.synchronize();
                            }

                            self.completionHandler.run((Object)null);
                        }
                    }
                }
            }
        }
    }

@ck: But for some reason this is a new bug that didn’t exist before…

yes we redid how anonymous things worked in some regards, sounds like a bug got in. I’ll log and see if your testcase will work, if it’s not enough I’ll ask for something more complete .

Thanks, logged as bugs://76090

@ck: Got it. Thanks.

Sure.

bugs://76090 got closed with status cannotrepro.

I haven’t been able to reproduce this. Do you still see it?

bugs://i64016 was closed as unable to reproduce.

Logged as bugs://i64016.