Vague Dotfuscator error on Xamarin.Android app - android

When running Dotfuscator on the release version of my Xamarin.Android app, I'm getting the following errors:
If I disable Dotfuscator, then everything works fine. The weird part is that it works fine on a previous version of the app. In this new version of the app, I only added a handful of Android ContentProviders and one NuGet package. Nothing else. Any ideas?
Update
So as Joe Sewel explains, the issue is not technically with Dotfuscator, but with Xamarin.Android. The system from Xamarin, while generating Java classes, is populating their names from strings pulled from the .NET Intermediary Language files without first checking if those strings can actually be used as Java class names.
In my case, the issue was caused because I had two too many obfuscated C# classes in my project. Dotfuscator was renaming one of my class to do (after going through its normal renaming cycle: ab, ac, ad, and so on). Obviously, do cannot be used as a Java class name because it's a Java reserved keyword, so it caused a syntax error in the Xamarin tools later on. Removing or having Dotfuscator ignore any two classes in my project, caused Dotfuscator not to reach the do name in its cycle, and the issue was fixed. So until this bug is fixed in Xamarin.Android, there is such a thing as obfuscating too many classes in your project.

What appears to be happening is that Dotfuscator is renaming a type to do - which is safe to do for non-library .NET Framework projects, because the .NET intermediate language doesn't reserve this word. Xamarin.Android's "glue" code is then creating Java code based on the obfuscated .NET assembly's type names, and since do is a reserved word in Java, this causes Java compiler errors.
To work around the issue, you could use the Dotfuscator Community user interface to exclude the type that is being renamed.
You can use the renaming map file (e.g., DotfuscatorReports\Release\Renaming.xml) to see the mapping between the original source code names and the obfuscated names, including with the built-in decoding tool.
I work on the Dotfuscator team, and am answering in that capacity. I've also filed an issue with Xamarin, linking to this question, regarding these errors.

Related

How does Android compile a Java method to an compiled method?

Recently I decompiled some Android APKs with dex2jar, jd-gui and Android studio.
Why can some classes' methods see the source code, and some classes' method can only see /compiled code/?
What's the difference between these two class when compiling?
What's more, I want to do the same compile work to my code to ensure the security. What tools can I look for ?
When Android Studio opens a .class file and cannot decompile the code, it just displays the "compiled code" message. There are lots of things that could prevent a decompilation because a lot of stuff is legal in byte code that is illegal in Java. (For instance, it's perfectly legal byte code to have a method named if or for, but those are Java keywords and cannot be used to name a Java method.) These sorts of things can easily show up when the .class files are processed by ProGuard, and possibly by other tools in the APK build process.
It can be happens because, your JAVA file cannot be readable due to improper bytecode or it may be encrypted. You cannot differentiate correct and incorrect JAVA files type.
Anyways, to properly compile your JAVA file, you can alternatively use Luyten (same as the jd-gui).
Source Link

Generate MainDexList.txt for Pre-5.0 Multidex app with reflection support

We are using android-maven-plugin to build a multidex application targeting Jelly Bean (4.3.x) with greater than 65k methods. The approach described here helps create a MainDexList.txt file, but does not automatically include classes that will be loaded by reflection.
Are any tools or processes available that can create a MainDexList.txt file with reflection support? [The majority of the classes we are loading via reflection are named via String constants...]
We are attempting to avoid manually running the app and dealing with NoClassDefFoundError messages one at a time.
To deal with the NoClassDefFoundError, you just need to add the MainDexList.txt to each of your projects. This should solve your initial errors right away. However, since your MainDexList.txt will still be empty, you will run into further issues.
To load the MainDexList.txt with a script instead of doing it manually, you can use this open source script by Google which will generate the exact class names that should be included in MainDexList.txt. Here is a link to the actual commit by Google:
https://android.googlesource.com/platform/dalvik/+/2bb6fe45bf620525ba34bd7303d7ecb597aa0689
To learn more (and also my source of information):
http://blog.osom.info/2014/10/generating-main-dex-list-file.html
Notes: This unfortunately does not support reflection however, DexClassLoader loads classes from .jar and .apk files containing a classes.dex entry. This may be worth looking at as well.
Hope this helps!

java.lang.NoSuchMethodError: org.json.JSONObject.getNames on Android due to conflicting libraries

I am creating a cross platform application in java using libgdx. I am using Json in the core project and was trying to deploy on Android when I received this error:
E/AndroidRuntime(2030): java.lang.NoSuchMethodError: org.json.JSONObject.getNames
I read around and I found out that Android has a built in Json library that uses that same package name as the Json library I added to my core project. The library I use has the getName() method and the Android library has a name() method. Is there a way for me to specify the library I want to use? Alternatively, is there a way for me to ignore the Android library?
Update: I tested accessing the JSON method in my android project using
JSONObject.getNames(TEST);
which should have given me null, but instead gave me the same error.
if you happen to use a lib, that uses the same namespace/package name as another, you are at the mercy of the classloader, which usually picks the first place, where it can find the class by name.
so the easiest way to circumvent this is either to use the same library and version as used on android or move your library in another package.
if the library in question allows it (licence etc) and is reasonable small, you might be easier off just pulling in the source files in your project and let the IDE do the refactoring magic. Also there are tools like jarjar.
There are some question on SO (Calling same Method having same packageName From Different JARs, Java, Classpath, Classloading => Multiple Versions of the same jar/project). So you might be able to circumvent this problem, but my gut feeling is, that you will end up in big mess.

.jar android library import into Xamarin project

There are several ways that Andorid aka-native code (Java code) could be integrated into Xamarin project. Official ways are listed in this article.
We are trying to use a Java Library Binding approach discribed in the article.
Our test andoid library is published on Github for this question specifically.
We've created it in Android Developer tools setting it as Java Android Library. It is built in Eclipse into a .jar format that tutorial on Xamarin site assumes to be sufficient.
If we are trying to bind .jar into our project in Visual Studio, the Object Explorer will show us the binding asseblie's namespace, but in code, even though the assembly is referenced, we can't access the methods and classes in the namespace, decleared in our test java android lib..
On the other hand, when we take almost any .jar, which is an android library on the internet (for example this one), we can bind it and access it's methods without a problem.
Please compare two .jar and if possible, let me know what is wrong with our test android library on github, that causes our namespace to be unavailable from code.
I read the same Binding a Java Library article you did, went through the instructions, and had no build errors. When I attempted to use the classes from my jar file, intellisense was not recognizing anything. Then I read the follow-on article on API Metadata Reference. This got me thinking that perhaps I should try editing the Transforms/Metadata.xml file. After editing that briefly to include a rename of the package, Visual studio allowed (after a compile) a reference to a class from the jar file. I then attempted to call a method from the class, and again, got another compiler error. So, I went back into the Metadata.xml file and added an entry to rename the method in question. I edited my code to call the renamed method, and Visual Studio compiled fine. I integrated this call into a unit test case, and it passed!
From my reading, it didn't seem necessary to edit the Metadata.xml file, but at least in my experience it seemed necessary. It uses XPATH on the obj/Release/api.xml file (as stated in API Metadata Reference). From that article there were examples for renaming both package & method names, so it wasn't much work for me to insert into my Metadata.xml file. In addition, I downloaded the OsmBindingDroidExample from the Binding a Java Library article and checked out their Metadata.xml file as well.
Here's my XML for reference as well:
<metadata>
<attr path="/api/package[#name='com.abc.def']" name="managedName">MyRenamedPackage</attr>
<attr path="/api/package[#name='com.abc.def']/class[#name='MyClass']/method[#name='originalJavaMethod']" name="managedName">RenamedDotNetMethod</attr>
</metadata>
So, now in my .NET code, I could write:
MyRenamedPackage.MyClass.RenamedDotNetMethod(...);
Hope this helps!
EDIT:
I've gotten a bit more familiar with the Xamarin toolkit, and have an update to make using this easier.
In order to limit the involvement of code that needs to interact with the jar methods, Xamarin allows you to create C# classes in the Additions folder. So, I created a wrapper class that exposes the methods in a managed C# class that other projects can access. Since it's C# there's no complaints from Visual Studio.
Here's what a wrapper class would look like going with my earlier example (obviously you'd pick a name more meaningful to the task at hand):
public class InovcationWrapper
{
public static void InvokeMethod(...)
{
MyRenamedPackage.MyClass.RenamedDotNetMethod(...);
}
}
Then in your project code, you'd have full intellisense if you just call your wrapper class:
InvocationWrapper.InvokeMethod(...);
This makes it much easier to work with and limits the amount of red squiggles to be ignored in your code. Hope this helps!

How does ADT optimize dead code for Android apps? [duplicate]

So, I've got a handful of "Utility" style classes in some of my projects. I'm curious if I can move them to an Android Library Project that contains all or most of my non-app specific glue code (wrappers and interfaces, mostly).
So, my question is what happens to the files I don't need in that library. I know Android Library Projects basically just copy their code into the other project, so if I say use 25% of the code in my "general purpose" library, will my app actually contain the bytecode for all 100%, or does it properly strip it down to only the stuff I need.
I had some issues with unused classes in Proguard in the past, so I'm just once-bitten, twice shy with the ADT now...
Unfortunately, all your projects will grow when the library is getting bigger - even if most contents of that library are not used. I tested it myself by creating an app A and a library L. If L is a library used in A, the classes.dex file (and therefore the A.apk file) is growing if I add more classes - even if they are not used.
To sum up: Right now I would create a basic library for certain things that are small and that may be used by many projects, and create a new library for every new component that is going to be larger and only is used by some projects. A good candidate for a new library would be a new UI component with multiple images defined in the resources. A good candidate for the base library are commonly-used methods and things like file caches, for example. Compiled code is compressed quite heavily for Dalvik, which you can see here. (The whole presentation is actually fun to watch :-)
Edit: If ProGuard is activated, it will also remove unused code for you. The default proguard.cfg is sufficient. It will not run on the (default) debug built, but when the final .apk is compiled. So it actually is possible!
I have used 3 level deep Android library projects successfully though it is kind of a pain. The primary use-case is when there are a set of resources and classes that you want to share across a few projects. Since I use a version control system, I would rather not use symlinks.
Note that Android Library projects also suffer greatly when dealing with resources. ADT will rebuild R.java once for each library, and each R.java will contain a copy of all resource ids from all libraries. The core problem here is that resources are regenerated for the entire project as a whole, and there is no way to "build a jar" for a dependency as would be expected with normal "libraries". We tried integrating with OpenFeint, and had all kinds of hell dealing with libraries and dependencies. I think we ended up just merging all the OpenFeint source and resource files into our own project and ditching the "Library" project as it was offering little value.
Android Library projects are a clunky way of sharing code between projects and have a number of drawbacks. I've found that everything accomplished with a Library project can also be accomplished with symlinks (symlink source into two projects). I've yet to find a usecase where an Android Library project offered something that wasn't easy to replicate with other, less fragile means.

Categories

Resources