facebook / litho

A declarative framework for building efficient UIs on Android.
https://fblitho.com
Apache License 2.0
7.71k stars 766 forks source link

Issue when using litho testing #1013

Open ahmedelmasry21 opened 1 month ago

ahmedelmasry21 commented 1 month ago

Version

0.48.0

Issues and Steps to Reproduce

Crash when using lithoViewRule.render in litho testing

java.lang.UnsatisfiedLinkError: no yoga in java.library.path: /Users/elmasry/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:. java.lang.RuntimeException: java.lang.UnsatisfiedLinkError: no yoga in java.library.path: /Users/elmasry/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:. at com.facebook.litho.TreeFuture.runAndGet(TreeFuture.java:385) at com.facebook.litho.TreeFuture.trackAndRunTreeFuture(TreeFuture.java:474) at com.facebook.litho.ComponentTree.doLayout(ComponentTree.java:2475) at com.facebook.litho.ComponentTree.requestLayoutWithSplitFutures(ComponentTree.java:2414) at com.facebook.litho.ComponentTree.requestRenderWithSplitFutures(ComponentTree.java:2141) at com.facebook.litho.ComponentTree.setRootAndSizeSpecInternal(ComponentTree.java:2063) at com.facebook.litho.ComponentTree.setSizeSpecForMeasure(ComponentTree.java:1698) at com.facebook.litho.ComponentTree.measure(ComponentTree.java:1129) at com.facebook.litho.LithoView.onMeasureInternal(LithoView.java:292) at com.facebook.litho.LithoView.onMeasure(LithoView.java:226) at android.view.View.measure(View.java:25833) at com.facebook.litho.testing.TestLithoView.measure(TestLithoView.kt:192) at com.facebook.litho.testing.LithoViewRule.render(LithoViewRule.kt:167) at com.facebook.litho.testing.LithoViewRule.render$default(LithoViewRule.kt:153) at com.deliveroo.rooblocks.components.video.VideoComponentTest.video component(VideoComponentTest.kt:26) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at com.facebook.litho.testing.LithoViewRule$apply$1.evaluate(LithoViewRule.kt:88) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:589) at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$2(SandboxTestRunner.java:290) at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:99) at java.base/java.util.concurrent.FutureTask.run(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.base/java.lang.Thread.run(Unknown Source) Caused by: java.util.concurrent.ExecutionException: java.lang.UnsatisfiedLinkError: no yoga in java.library.path: /Users/elmasry/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:. at java.base/java.util.concurrent.FutureTask.report(Unknown Source) at java.base/java.util.concurrent.FutureTask.get(Unknown Source) at com.facebook.litho.TreeFuture.runAndGet(TreeFuture.java:335) at com.facebook.litho.TreeFuture.trackAndRunTreeFuture(TreeFuture.java:474) at com.facebook.litho.ComponentTree.doLayout(ComponentTree.java:2475) at com.facebook.litho.ComponentTree.requestLayoutWithSplitFutures(ComponentTree.java:2414) at com.facebook.litho.ComponentTree.requestRenderWithSplitFutures(ComponentTree.java:2141) at com.facebook.litho.ComponentTree.setRootAndSizeSpecInternal(ComponentTree.java:2063) at com.facebook.litho.ComponentTree.setSizeSpecForMeasure(ComponentTree.java:1698) at com.facebook.litho.ComponentTree.measure(ComponentTree.java:1129) at com.facebook.litho.LithoView.onMeasureInternal(LithoView.java:292) at com.facebook.litho.LithoView.onMeasure(LithoView.java:226) at android.view.View.$$robo$$android_view_View$measure(View.java:25833) at android.view.View.measure(View.java) at com.facebook.litho.testing.TestLithoView.measure(TestLithoView.kt:192) at com.facebook.litho.testing.LithoViewRule.render(LithoViewRule.kt:167) at com.facebook.litho.testing.LithoViewRule.render$default(LithoViewRule.kt:153) at com.deliveroo.rooblocks.components.video.VideoComponentTest.video component(VideoComponentTest.kt:26) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) ... 13 more Caused by: java.lang.UnsatisfiedLinkError: no yoga in java.library.path: /Users/elmasry/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:. at java.base/java.lang.ClassLoader.loadLibrary(Unknown Source) at java.base/java.lang.Runtime.loadLibrary0(Unknown Source) at java.base/java.lang.System.loadLibrary(Unknown Source) at com.facebook.soloader.SoLoader.loadLibraryOnNonAndroid(SoLoader.java:831) at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:787) at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:774) at com.facebook.yoga.YogaNative.<clinit>(YogaNative.java:16) at com.facebook.yoga.YogaConfigJNIBase.<init>(YogaConfigJNIBase.java:23) at com.facebook.yoga.YogaConfigJNIFinalizer.<init>(YogaConfigJNIFinalizer.java:12) at com.facebook.yoga.YogaConfigFactory.create(YogaConfigFactory.java:12) at com.facebook.litho.yoga.LithoYogaFactory.createYogaConfig(LithoYogaFactory.java:27) at com.facebook.litho.NodeConfig.<clinit>(NodeConfig.kt:34) at com.facebook.litho.LithoNode.createYogaNodeWriter(LithoNode.java:1350) at com.facebook.litho.LithoNode.buildYogaTree(LithoNode.java:545) at com.facebook.litho.LithoNode.calculateLayout(LithoNode.java:664) at com.facebook.litho.Layout.measureTree(Layout.java:65) at com.facebook.litho.LayoutTreeFuture.layout(LayoutTreeFuture.java:204) at com.facebook.litho.LayoutTreeFuture.calculate(LayoutTreeFuture.java:83) at com.facebook.litho.LayoutTreeFuture.calculate(LayoutTreeFuture.java:34) at com.facebook.litho.TreeFuture$1.call(TreeFuture.java:81) at com.facebook.litho.TreeFuture$1.call(TreeFuture.java:72) at java.base/java.util.concurrent.FutureTask.run(Unknown Source) at com.facebook.litho.TreeFuture.runAndGet(TreeFuture.java:285) ... 32 more

Expected Behavior

render function works without crashing

Link to Code

lithoViewRule.render { CustomComponent() }

astreet commented 1 month ago

Unfortunately as Yoga is a native dependency, getting it to work with local unit tests with gradle is a pain. The best suggestion is to follow something similar to the setup in this project itself:

1) Copy lib/yoga and lib/yogajni in your project 2) Add this to your settings.gradle and something like this to your root build file (you may want to make a LithoTest type) 3) Add a switch to include the yogajni dep for non-release builds like this

Alternately, if easier, you could clone the yoga repo, build Yoga targeting your required architecture, and then add the library to your classpath manually (as done here: https://github.com/facebook/litho/blob/master/build.gradle#L98-L111)