Xamarin Realm no realmobject has linker stripped them - android

I am receiving an exception at runtime as follows.
"No realmobject. Has linker stripped them...."
My solution includes a PCL, Android and IOS project with Visual studio Mac and the realm package 1.6.0 installed in each project. I've also checked that Fodyweaver.xml includes the correct reference and all packages have th same version.
When I have the PCL included in the same folder as the solution (i.e like the default multiplatform solution with PCL) everything works ok.
However I moved the PCL project which includes all the realm logic to a separate folder so I can use it across multiple solutions. My solution now includes the PCL from this external folder and the iOS and Android project also reference the realm packages. the app compiles fine but when I run the application it now receives this exception on the first call to use realm.getinstance.
If Input the PCL project back into the same folder as the main solution as originally created it works fine.
can anyone advise a fix for this ?

I've solved the issue now. Firstly I had applied the solution from #sushhangover, but it didn't work straight off.
After some investigation I discovered the compiler was not weaving the classes and realm objects into the library at all.
I simply loaded the library independently of my main solution, removed and reloaded realm packages and Fody, cleaned it all, rebuild All. and then I could see the fodyweaver working properly. I then added the reference back into my main solution and it all works .

This is the same issue I have when placing my RealmObject models into a separate library (PCL or NetStd) as I use a Viper architecture and I share the same model across multiple solutions.
When Realms.Realm.GetInstance(....) is called the Realm initialization assumes the RealmObjects will be in the same assembly or that the assembly containing is already loaded, but they are not in this case. You can tell this is the case as a compiler warning is issued in the assembly build (via the Fody processing) that is calling GetInstance but that does not have any RealmObjects in it:
Warning: Fody/RealmWeaver: Default schema appears to be empty. This is not an error if you don't have any RealmObject inheritors declared. Otherwise it may be a bug with the weaver. (GeneticCancerSelectors)
So I add a static class to my Realm model library:
public static class RealmModel
{
public static Realms.Realm GetInstance() => GetInstance("");
public static Realms.Realm GetInstance(string databasePath) => GetInstance(new RealmConfiguration(databasePath));
public static Realms.Realm GetInstance(RealmConfigurationBase config = null) => Realms.Realm.GetInstance(config);
public static Task<Realms.Realm> GetInstanceAsync(RealmConfigurationBase config) => Realms.Realm.GetInstanceAsync(config);
}
Now when you need to get a Realm instance, do not call:
Realms.Realm.GetInstance()
But call the one in your Model assembly:
RealmModel.GetInstance()

Thanks to Chris Baxter.
That's my situation.
[WPF Application, Fody 3.0.3, Realm 3.4.0]
Exception: No RealmObjects. Has linker stripped them?
...This is my First Time using Realm, and It's really bad feeling...
A [Brand New] Blank WPF Project
Nuget => Realm
Required FodyWeavers.xml file Created in Solution Folder, because Nuget can't
do this for you now.
(Somehow I Update Then Downgrade a latest version of Fody, after
recongized that Realm don't support Any Fody which version newer
than 3.X)
Awful Exception Occurs, ooooops!
(hours work with System
Auth, SpecialFolder, etc... Until I Discovered Chris Baxter's
answer)
Xml file content:
<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
<RealmWeaver/>
</Weavers>
How to Solve the Problem:
Just Clean And ReBuild Solution, Problem Solved.

Related

Visual Studio can't find extension methods Splat.BitmapMixins.FromNative() and Splat.BitmapMixins.ToNative() in Android app

While upgrading a Xamarin app that leverages Splat's bitmap functionality we are getting errors around the use of the methods mentioned in the title:
'IBitmap' does not contain a definition for 'ToNative' and no accessible extension method 'ToNative' accepting a first argument of type 'IBitmap' could be found (are you missing a using directive or an assembly reference?)
In an effort to troubleshoot the problem we have created a new sample Android-only Xamarin app and referenced Splat and Splat.Drawing via NuGet. We then added calls to these methods and have reproduced the error:
public void Bar(IBitmap source)
{
Bitmap native = source.ToNative();
IBitmap bitmap = native.FromNative();
}
It seems as though the Andriod app may not be referencing the proper build of the Splat libraries. When I monitor paths containing %USERPROFILE%\.nuget\packages\splat in ProcMon I don't see any attempt by Visual Studio to open/read anything other than files in the .\netstandard2.0 directories during the build process.
When I open the netstandard2.0 libraries in DotPeek I can see that the class BitmapMixins is not included, but it is included in the monoandroid90 builds.
How do I get the reference to Splat in the Android project to pull in the proper build of Splat?
Example project can be found here: https://github.com/jctlp/SplatBitmap
The error caused by that you did not have the extension methods to assist with dealing with Bitmaps of ToNative and FromNative.
Please do not add reference by installing the Splat from NuGet directly. Add reference to the whole project of Splat would be okay.
Download the whole Splat project from the link below.
https://github.com/reactiveui/splat.git
I create a Xamarin.forms app named App1. And create a class Class2.cs in App1.Android. When I add reference to Splat from the project. It works well with ToNative and FromNative extension method.
Please note: Do not use the Bitmap, use Android.Graphics.Drawables.Drawable or var instead.
public void Bar(IBitmap source)
{
Android.Graphics.Drawables.Drawable native = source.ToNative();//var
IBitmap bitmap = native.FromNative();
}

Android library with dependency not resolving properly

So I have an Android library project, SimpleWidget. I publish it to jcenter.
I can make a new project and add implementation 'my.project:simplewidget:1.2.3' and everything works as expected, I can use SimpleWidget instances and their public APIs.
Now I make another Android library project, ComplexWidget. ComplexWidget is a subclass of SimpleWidget. I add implementation 'my.project:simplewidget:1.2.3' to the build.gradle and everything resolves, and in fact I can even get away without lint yelling for something super basic like ComplexWidget complexWidget = new ComplexWidget().
However, the project will not compile. Any ComplexWidget method that has a return or parameter type of SimpleWidget (e.g., many of the inherited methods, or an interface that accepts SimpleWidget arguments, or a Factory that returns SimpleWidget instances) will not compile and Android Studio complains that "Cannot access my.project.SimpleWidget".
Not sure if I should even mention it for fear of muddying the waters, but if I command click SimpleWidget in, for example, public class ComplexWidget extends SimpleWidget, I get a warning at the top of the file that "Library source does not match the byetcode for the class SimpleWidget".
Any ideas?
TYIA
use api 'my.project:SimpleWidget:1.2.3' instead

Scala reflection java.rmi dependency, can it work on Android?

I would like to use the Scala (2.11) reflection package's runtime mirror in a Scala application compiled for android which is being build using Scala on android.
I was able to fiddle with ProGuard options in order to make it include the required Scala classes. However when I try to get a mirror instance:
universe.runtimeMirror(this.getClass.getClassLoader)
(Indeed it fails during the lazy computation of universe)
The application crashes in run time:
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/rmi/Remote;
at scala.reflect.internal.Definitions$DefinitionsClass.RemoteInterfaceClass$lzycompute(Definitions.scala:370)
at scala.reflect.internal.Definitions$DefinitionsClass.RemoteInterfaceClass(D efinitions.scala:370)
at scala.reflect.runtime.JavaUniverseForce$class.force(JavaUniverseForce.scal a:255)
at scala.reflect.runtime.JavaUniverse.force(JavaUniverse.scala:16)
at scala.reflect.runtime.JavaUniverse.init(JavaUniverse.scala:147)
at scala.reflect.runtime.JavaUniverse.<init>(JavaUniverse.scala:78)
at scala.reflect.runtime.package$.universe$lzycompute(package.scala:17)
at scala.reflect.runtime.package$.universe(package.scala:17)
This crash is for me as expected as it isn't:
It is expected as java.rmi is not part of the Android API and I should expect any code trying to load its classes to crash.
It is unexpected as I didn't know that Scala's reflect package used java.rmi
I have traced the code to were rmi is required, that is to JavaUniverse (a trait mixed in JavaUniverse class) force method:
...
definitions.RemoteInterfaceClass
...
Which leads to DefinitionsClass:
lazy val RemoteInterfaceClass = requiredClass[java.rmi.Remote]
Am I wrong to think that this is a no-go for Scala reflection in Android?
If I am, what could be a workaround to this problem?
To summarize your solution and a related solution, it is sufficient to add two files, and modify build.sbt to include:
dexAdditionalParams in Android += "--core-library"
Add java/rmi/Remote.java to your project with the content:
package java.rmi;
public interface Remote {}
Add java/rmi/RemoteException.java to your project with the content:
package java.rmi;
public interface RemoteException {}

Runtime error using Xamarin Android with F# and ReactiveUI

I have created a Xamarin Android project that is using F# and ReactiveUI.
When loading my Dashboard, I encounter a runtime exception (of type MissingMethodException) on the inherit line of this code snippet:
type DashboardViewModel(?host: IScreen) =
inherit ReactiveViewModel()
let host = LocateIfNone host
member __.Title with get() = "Dashboard"
interface IRoutableViewModel with
member __.HostScreen = host
member __.UrlPathSegment = "Dashboard"
The error message reads
Method 'Microsoft.FSharp.Quotations.FSharpExpr.Deserialize40' not found.
The ReactiveViewModel type is a thin wrapper around ReactiveObject:
type ReactiveViewModel() as this =
inherit ReactiveObject()
let mutable message = noMessage
let uiContext = SynchronizationContext.Current
member __.SyncContext with get() = uiContext
member this.Message
with get() = message
and set(value) =
this.RaiseAndSetIfChanged(&message, value, "Message") |> ignore
if message <> noMessage then this.RaiseAndSetIfChanged(&message, noMessage, "Message") |> ignore
member val MessageSent =
this.WhenAnyValue(toLinq <# fun vm -> vm.Message #>).ObserveOn(RxApp.MainThreadScheduler).Where(fun m -> m <> noMessage) with get
The project is open source: at the moment, it contains very little content. It can be found at https://github.com/SpiegelSoft/Astrid.
I have submitted a bug on the Xamarin bug tracker: https://bugzilla.xamarin.com/show_bug.cgi?id=51000
Are there any known fixes I can implement myself, so that I can close the bug of my own accord?
UPDATE 1
I've been investigating this issue this weekend.
The FSharp.Core version that is loaded is stuck on the obsolete version 2.3.98.1. This corresponds to the FSharp.Core.dll file in
C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework\MonoAndroid\v1.0
I have tried to remove this version and load the NuGet package FSharp.Core; however, when I build the Android project, the path always reverts to the obsolete file in the Reference Assemblies path.
Is there a way to override this behaviour?
UPDATE 2
Replacing the FSharp.Core.dll file in the Reference Assemblies path fixes the issue, but this is a very unsatisfactory sticking plaster, which I can't ask my users to apply. Ideally, I would like to find a way to prevent the .Droid project from loading FSharp.Core from the GAC rather than the NuGet package.
I just ran into a very similar issue the other day. My android app had a reference to a Profile7 F# PCL library, which made use of List.unfold, which I believe was introduced in F# 4. When I used the library in my app, I saw a MissingMethodException similar to what you are seeing. The version of FSharp.Core that Xamarin references by default when creating a new Android app didn't have this newer method. I got around it by editing the .fsproj file for the app to remove the original reference to FSharp.Core, and replaced it with a reference to the newer version ( I copy/pasted the tag from the PCL .fsproj file). It looks something like this:
<Reference Include="FSharp.Core">
<Name>FSharp.Core</Name>
<Private>True</Private>
<AssemblyName>FSharp.Core.dll</AssemblyName>
<HintPath>$(MSBuildExtensionsPath32)\..\Reference Assemblies\Microsoft\FSharp\.NETCore\$(TargetFSharpCoreVersion)\FSharp.Core.dll</HintPath>
</Reference>
I was suprised to find that this seems to have fixed the problem for me. I'm not sure if I'll run into other issues down the line, but it may be worth trying this if you havent already.
UPDATE If this doesn't work immediately, follow the sequence of steps in Rob Lyndon's answer.
It appears that this has been fixed by the GitHub commit
https://github.com/xamarin/xamarin-android/commit/df41af046000556ed82f638e8041b7f718966a92
which removes FSharp.Core from the list of framework assemblies, and allows the project to be built without the NuGet FSharp.Core assembly being replaced.
Until this fix is released into the SDK, there is a workaround. The answer submitted by user3850711 works, but you need to apply the changes in a specific sequence, because otherwise the reference will be overwritten during the build.
Delete the existing reference to FSharp.Core.
Install or reinstall the FSharp.Core NuGet package.
Unload the project and add <HintPath>packages\FSharp.Core.4.0.0.1\lib\portable-net45+monoandroid10+monotouch10+xamarinios10\FSharp.Core.dll</HintPath> to the FSharp.Core project reference.

Upgrading from Cordova 2.5 to Cordova 3.0 , facing issue while using CordovaInterface

I am migrating my project to Cordova 3 from Cordova 2.5. Followed the migration process mentioned in
http://cordova.apache.org/docs/en/3.0.0/guide_cli_index.md.html
But, unfortunately getting the following error
Preparing android project [Error: No Java files found which extend
CordovaActivity.]
In our app, we have a class which extends activity and implements CordovaInterface. And moreover this class is in the location mentioned in config.xml.
Yet, I am facing the following error. Is it mandatory to substitute CordovaInterface with CordovaActivity? I am pretty sure that will not be the mandatory case.
This is causes by a bonehead, broken, Cordova build system.
If you simply add any old class in your source tree, next to your activity, that extends CordovaActivity, the build will work.
You don't even have to use the class, just make one.
It's like they are having an internal debate about how it should work, and one side screwed over the other by making the build fail if they didn't get their way.
Example:
import org.apache.cordova.CordovaActivity;
/**
* This class is simply here to make sure Cordova will build. Without it, even
* though it's not used or otherwise referenced, you will get a build error that
* looks like "Error: No Java files found which extend CordovaActivity".
*
* This applies as of Cordova 3.5.0. It should be re-tested when upgrading to
* Cordova 4.x.
*
*/
public class FakeCordovaActivityForBuild extends CordovaActivity {
}
With luck, someone on the dev team will notice this little conflict and fix it, I suppose it should be listed as a bug in their system, but I have not added it.
Interestingly, replacing CordovaInterface with the CordovaActivty (and appropriate changes) resolved the issue. There is no mention of mandatory usage of CordovaActivity in release notes documentation.
However, need to refine code inside the Java file which extends CordovaActivity.

Categories

Resources