Linker and LayoutInflater.Inflate(int, Android.Views.ViewGroup) - linker

i use Mvx.MvxFrameControl successfully with most views. One of these views uses a custom control built from scratch. In release mode only, while inflating this view, the app crashes.
The log shows that a method has been optimized away and is missing.
at <unknown> <0xffffffff>
at (wrapper managed-to-native) object.wrapper_native_...
at Android.Runtime.JNIEnv.CallObjectMethod (intptr,intptr,Android.Runtime.JValue[])
at Android.Views.LayoutInflater.Inflate(int, Android.Views.ViewGroup)
at Cirrious.MvvmCross.Binding.Droid.BindingContext.MvxAndroidBindingContext.CommonInflate(int,Android.View.ViewGroup, IMvxLayoutInfactorFactory)
....
So i tried to add these lines to the MainApp constructor in the MainApp class.
public class MainApp : Application
{
public MainApp(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
//For linker only
Android.Views.LayoutInflater inflater = null;
if(inflater != null)
inflater.Inflate(0, null);
}
I was hoping the linker would not optimize the method away. But no luck. The method is still missing. How to fix this ?
EDIT: I've tryed Cheesebaron.HorizontalListView.Demo project in release mode in the Android 4.3 simulator and it aslo crashes.
EDIT: it seems the linking problem is related to all classes deriving from AdatperView<T>
EDIT: more stacktrace
01-03 03:20:46.185 E/mono-rt ( 2106): Stacktrace:
01-03 03:20:46.185 E/mono-rt ( 2106):
01-03 03:20:46.195 E/mono-rt ( 2106): at <unknown> <0xffffffff>
01-03 03:20:46.195 E/mono-rt ( 2106): at (wrapper managed-to-native) object.wrapper_native_0xb6360af0 (intptr,intptr,intptr,Android.Runtime.JValue[]) <0xffffffff>
01-03 03:20:46.195 E/mono-rt ( 2106): at Android.Runtime.JNIEnv.CallObjectMethod (intptr,intptr,Android.Runtime.JValue[]) <0x00068>
01-03 03:20:46.195 E/mono-rt ( 2106): at Android.Views.LayoutInflater.Inflate (int,Android.Views.ViewGroup) <0x00147>

This is a bug. The workaround is to provide a custom linker script by adding a new file to your project with a Build action of LinkDescription and the file contents:
<linker>
<assembly fullname="Mono.Android">
<type fullname="Android.Widget.AdapterView">
<method name="GetGetAdapterHandler" />
<method name="GetSetAdapter_Landroid_widget_Adapter_Handler" />
</type>
</assembly>
</linker>

Related

Register an addon in Episerver CMS 12

Plugin UI are developed in a separate MVC project and CMS 12 is in another projects. Following is a test solution that just to explain the issue we are having.
Solution structure
Please consider followings
The TestAddon project is a Simple MVC project with basic UI. We need to get this UI rendered in a CMS 12 Admin menu. We have created a menu provider as well.
Then build the TestAddon project and copied DLLs to CMS-> bin folder.
Created module/_protected folder and added TestAddon/TestAddon.zip
module.config was created as described in the documentation(https://world.optimizely.com/documentation/developer-guides/CMS/configuration/Configuring-moduleconfig/)
<module productName="TestAddon" loadFromBin="false" tags="EPiServerModulePackage" clientResourceRelativePath="1.0.0">
<assemblies>
<add assembly="TestAddon" />
<add assembly="TestAddon.Views" />
</assemblies>
<route url="{controller}/{action}" >
<defaults>
<!--<add key="moduleArea" value="TestAddon" />-->
<add key="controller" value="CustomAdminPage" />
<add key="action" value="Index" />
</defaults>
</route>
<clientResources>
<!-- <add name="myscript" path="ClientResources/index.js" resourceType="Script" ></add> -->
</clientResources>
<clientModule>
<moduleDependencies>
<add dependency="CMS" />
<add dependency="Shell"/>
<add dependency="EPiServer.Cms.UI.Admin" type="RunAfter"/>
<add dependency="EPiServer.Cms.UI.Settings" type="RunAfter"/>
</moduleDependencies>
<requiredResources>
</requiredResources>
</clientModule>
</module>
Set Auto discovery in startup file
services.Configure<ProtectedModuleOptions>(x => x.AutoDiscovery = EPiServer.Shell.Configuration.AutoDiscoveryLevel.Modules);
When we then start the project it is giving following error
Error Screenshot
Stacktrace
When we removed the auto discovery setting form startup class. It works to build the project
Does anyone have experienced this?
Please point me in a correct direction
You don't need to copy files to your sample project for local testing. You can add a project reference to your add-on project instead, then add this in your sample project's startup so the files are loaded correctly:
var moduleName = typeof(SomeClassInYourAddOn).Assembly.GetName().Name;
services.Configure<CompositeFileProviderOptions>(options =>
{
options.BasePathFileProviders.Add(new MappingPhysicalFileProvider(
$"/EPiServer/{moduleName}",
string.Empty,
Path.GetFullPath($"..\\..\\src\\{moduleName}")));
});
services.Configure<ProtectedModuleOptions>(options =>
{
options.Items.Add(new ModuleDetails { Name = moduleName });
});
Not sure if this is needed, but I don't think protected modules are auto discovered. So if you have a configuration method in your add-on that consumers of your add-on need to call, then you can add this in the method:
var moduleName = typeof(SomeClassInYourAddOn).Assembly.GetName().Name;
services.Configure<ProtectedModuleOptions>(options =>
{
if (!options.Items.Any(i => i.Name.Equals(moduleName, StringComparison.OrdinalIgnoreCase)))
{
options.Items.Add(new ModuleDetails() { Name = moduleName });
}
});
Then your add-on is added even if auto discovery is not enabled.

Retrieve unity container type registration from configuration file in PRISM 7

The configuration section for the unity container:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container>
<register type="IProductInfo, Core.Interface" mapTo="Classes.ProductInfo, Core">
<constructor>
<param name="Name" value="Product Name" />
<param name="Version" value="V1.2.65.30865" />
</constructor>
</register>
</container>
The types are registered in the App.xaml.cs file:
public partial class App : PrismApplication
{
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
UnityConfigurationSection section = (UnityConfigurationSection)config.GetSection("unity");
section?.Configure(containerRegistry.GetContainer());
}
}
However, because of the container abstraction built in the PRISM 7 version, the container instance doesn't match with the required parameter in the Configure method. The following error is produced by the compiler:
Error CS1503 Argument 1: cannot convert from 'Unity.IUnityContainer' to 'Microsoft.Practices.Unity.IUnityContainer'
Question: How can I retrieve the correct container instance to pass as a parameter of the Configure method
P.s. There is already a similar question on the same issue on StackOverflow. However, the answer doesn't provide a solution to the instantiation problem described above.
You're using incompatible libraries. UnityConfigurationSection expects a Microsoft.Practices.Unity.IUnityContainer (from an old unity version, three-something, most likely), while GetContainer produces a Unity.IUnityContainer (from a rather recent unity).
You should either upgrade your Unity.Configuration package or downgrade Prism...

Load Time Weaving in Spring Framework not logging properly

Is Load time Weaving(LTW) good choice for Enterprise Level Application with JSF as user interface and containing 6k+ classes?
Performance metrics has be to generated for the whole application but it is not able to generate for JSF managed Bean like LoginMBean. However #Component is there so is it possible that it can work with AspectJ(LTW)? aop.xml is added and aspectJWeaver path is also added to vm arguments.
<aspectj>
<weaver
options=" -verbose -showWeaveInfo -Xset:weaveJavaxPackages=true -Xreweavable">
<include within="com.x.login..*" />
<include within="com.x.aspects.Aspect" />
</weaver>
<aspects>
<aspect name="com.x.aspects.Aspect" />
</aspects>
</aspectj
package com.x.login;
#Component
#Scope("session")
public class LoginMBean extends AbstractMbean {
#Autowired
LoginService loginService ;
public void loginUserData(){
LoginInfo info= new LoginInfo();
//setter for info object
//some nested method calls
loginService.insertLoginData(info);
}
}
package com.x.login.service.impl;
#Service("LoginService")
public class LoginServiceImpl implements LoginService{
#Autowired
GenericCrudService genericCrudService ;
public void insertLoginData(LoginInfo info){
//some nested method calls
try{
genericCrudService.saveEntity(info);
}catch(Exception e){
//log exception
}
}
}
package com.x.aspect.config;
#Configuration
#ComponentScan(basePackages = { "com.x" })
#EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)
public class AspectConfig {
}
package com.x.aspects;
#Component
#Aspect
public class Aspects {
private static Logger Logger= LoggerFactory.getLogger(Aspects.class);
#Pointcut("execution(* *(..)) && cflow(execution(* com.x.login..*(..)))")
public void methodsToBeProfiled() {}
#Around("methodsToBeProfiled()")
public Object methodsToBeProfiled(ProceedingJoinPoint point) throws Throwable {
StopWatch sw = new StopWatch(getClass().getSimpleName());
try {
sw.start(point.getSignature().getName());
return point.proceed();
} finally {
sw.stop();
Logger.info("Elapsed Time, Package Name, Method Name");
Logger.info(sw.prettyPrint());
Logger.info("Package Name: " + point.getStaticPart());
}
}
}
AspectJ Log :
[ParallelWebappClassLoader#17c8dbdf] info register aspect com.x.aspects.Aspects
[ParallelWebappClassLoader#17c8dbdf] info register aspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
[ParallelWebappClassLoader#17c8dbdf] info register aspect org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect
[ParallelWebappClassLoader#5e68f202] weaveinfo Join point 'method-execution(void com.x.aspects.Aspects.methodsToBeProfiled())' in Type 'com.x.aspects.Aspects' (Aspects.java:36) advised by around advice from 'com.x.aspects.Aspects' (Aspects.java) [with runtime test]
[ParallelWebappClassLoader#5e68f202] weaveinfo Join point 'method-execution(java.lang.String com.x.login.PSMVProperties.getMultiDb())' in Type 'com.x.login.PSMVProperties' (PSMVProperties.java:27) advised by around advice from 'com.x.aspects.Aspects' (Aspects.java) [with runtime test]
[ParallelWebappClassLoader#5e68f202] weaveinfo Join point 'method-execution(void com.x.login.MultiDatabase.loadAEFormRestrictions(com.x.qnccore.service.GenericCrudService, java.lang.String, org.springframework.web.context.WebApplicationContext))' in Type 'com.x.login.MultiDatabase' (MultiDatabase.java:275) advised by around advice from 'com.x.aspects.Aspects' (Aspects.java) [with runtime test]
[ParallelWebappClassLoader#5e68f202] weaveinfo Join point 'method-execution(void com.x.login.QuestionMBean.setRecordLock(boolean))' in Type 'com.x.login.QuestionMBean' (QuestionMBean.java:146) advised by around advice from 'com.x.aspects.Aspects' (Aspects.java) [with runtime test]
[ParallelWebappClassLoader#5e68f202] weaveinfo Join point 'method-execution(java.lang.String com.x.login.RequestPojo.getTenantid())' in Type 'com.x.login.RequestPojo' (RequestPojo.java:18) advised by around advice from 'com.x.aspects.Aspects' (Aspects.java) [with runtime test]
[ParallelWebappClassLoader#5e68f202] weaveinfo Join point 'method-execution(void com.x.login.RequestPojo.setTenantid(java.lang.String))' in Type 'com.x.login.RequestPojo' (RequestPojo.java:23) advised by around advice from 'com.x.aspects.Aspects' (Aspects.java) [with runtime test]
[ParallelWebappClassLoader#17c8dbdf] weaveinfo Join point 'method-execution(void com.x.login.service.impl.LoginServiceImpl.insertLoginData(com.x.agx.admin.bus.entity.LoginInfo))' in Type 'com.x.login.service.impl.LoginServiceImpl' (LoginServiceImpl.java:427) advised by around advice from 'com.x.aspects.Aspects' (Aspects.java) [with runtime test]
[ParallelWebappClassLoader#17c8dbdf] weaveinfo Join point 'method-execution(java.util.List com.x.login.service.impl.LoginServiceImpl.getFailedLoginAttemptUsingIp(java.util.HashMap))' in Type 'com.x.login.service.impl.LoginServiceImpl' (LoginServiceImpl.java:442) advised by around advice from 'com.x.aspects.Aspects' (Aspects.java) [with runtime test]
spring-config.xml
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<context:load-time-weaver aspectj-weaving="on" />
Metrics log
ms % Task name
-----------------------------------------
00003 100% insertLoginData
2019-07-30 15:14:19,550 INFO c.a.a.Aspects [http-nio-8080-exec-10] Package Name: execution(void com.x.login.service.impl.LoginServiceImpl.insertLoginData(LoginInfo))
2019-07-30 15:14:19,554 INFO c.a.a.Aspects [http-nio-8080-exec-10] Elapsed Time, Package Name, Method Name
2019-07-30 15:14:19,555 INFO c.a.a.Aspects [http-nio-8080-exec-10] StopWatch 'Aspects': running time (millis) = 4
LoginMBean is jsf managed for login.xhtml.
Is it JSF issue or because of wrong pointcut?
LoginMBean is not appearing in woven classes.
Please help what is wrong above.I am unable to get
performance metrics for any method in LoginMBean class.
Looking at your log, it looks like LoginMBean is not exposed to the AspectJ weaver. At least I do not see any weaveinfo ... in Type 'com.x.login.LoginMBean'. So
either the class is loaded and woven later (you can grep your log for weaveinfo.*LoginMBean further down the log after you are sure the class was loaded and used by JSF)
or it is not woven at all (if you do not find such a log entry). Then you are having a classloader issue, i.e. somehow the AspectJ weaving agent was not registered on the classloader responsible for loading LoginMBean. Then it would be interesting to know which application server you are using and what your command JVM line looks like (should be something with -javaagent:....
Please follow up on this answer either via commenting or via updating your question with more information. Ideally, produce and publish an MCVE on GitHub.

Spring AOP is being invoked unexpectedly

I have configured Spring AOP for 2 different packages in our application to log exceptions.
There are 2 different configurations for each package:
<aop:config>
<aop:aspect id="aspectLoggging" ref="abcExceptionAspect">
<aop:pointcut id="pointCut"
expression="execution(* com.abc.*.*(..))" />
<aop:before method="logBefore" pointcut-ref="pointCut" />
<aop:after-throwing method="logExceptionABC"
throwing="error" pointcut-ref="pointCut" />
<aop:after method="logAfter" pointcut-ref="pointCut" />
</aop:aspect>
</aop:config>
<aop:config>
<aop:aspect id="aspectLoggging" ref="xyzlogAspect">
<aop:pointcut id="pointCut"
expression="execution(* com.xyz.*.*(..))" />
<aop:before method="logBefore" pointcut-ref="pointCut" />
<aop:after method="logAfter" pointcut-ref="pointCut" />
<aop:after-throwing method="logExceptionXYZ"
throwing="error" pointcut-ref="pointCut" />
</aop:aspect>
</aop:config>
In a service method call, there are calls to the methods of the classes belonging to each of these packages:
public void method()
{
method1(); -> package abc
method2(); -> package xyz
}
Some exception occurs in method2 which invokes logExceptionXYZ method where we are wrapping it in a generic exception, say ExceptionXYZ, and throwing it further.
But some how after this, the logExceptionABC method also gets invoked and throws a generic exception , say ExceptionABC.
I'm not able to understand as why logExceptionABC method is getting invoked?
Please let me know if someone knows about such an issue!
Regards,
Rahul
Same id is being assigned to both the aop:aspect tags. Similar is the case with the aop:pointcut tags as well.
Try with assigning unique IDs.

how to call testng.xml from java main method?

I have testng.xml file created.
Is there any way to run this file from java main method?
Something like -
Class test {
public static void main ( String [ ] args)
{
Run(testng.xml);
}
}
You can run testng directly from commandline, probably make a bat file on top of it or use jenkins to trigger it. Refer here
or
If you want it in main, then you can try
TestListenerAdapter tla = new TestListenerAdapter();
TestNG testng = new TestNG();
List<String> suites = Lists.newArrayList();
suites.add("c:/tests/testng1.xml");//path to xml..
suites.add("c:/tests/testng2.xml");
testng.setTestSuites(suites);
testng.run();
Please try below code and make sure you have testNG jar added in your jar manifest file.
public static void main(String[] args)
{
org.testng.TestNG.main(args);
}
now you can pass all the parameters to your jar which are same for testNG jar file.
e.g.
java -jar yourjar.jar testng.xml
or
java -jar yourjar.jar -testclass org.test.xyz.java
This work for me. More details here.
// Create object of TestNG Class
TestNG runner=new TestNG();
// Create a list of String
List<String> suitefiles=new ArrayList<String>();
// Add xml file which you have to execute
suitefiles.add("C:\\Automation Test\\Git\\vne_automation\\testng.xml");
// now set xml file for execution
runner.setTestSuites(suitefiles);
// finally execute the runner using run method
runner.run();
Hope this helps!
All the answers above works like a charm but there is one limitation that
it would run unless and untill you remove the scope tag in pom.xml
In pom.xml there would be maven dependancy for testNg and in there
there would be one scope tag which limits our jar to only upto test
Just remove that one
I didn't get any error and XML path is correct. But It just end execution with failed test cases. It does not open firefox browser.
I am using testng annotation (i.e. #Before Suite,#Test, #group etc ) inside classes whereas it successfully execute using Testng Suite in eclipse.
<!-- suite name="Example" parallel="methods" thread-count="2" parallel="false" preserve-order="true"> -->
<suite name="Example Donate System" verbose='1'>
<test name="Agency" >
<packages>
<package name="com.Donatesystem.AgencyController" />
</packages>
</test>
</suite>

Resources