Dynamically creating an Interface with static method in Android using ByteBuddy - byte-buddy

I have this code which works fine with byte buddy in normal Java but it does not work in Android.
Class c = new ByteBuddy().makeInterface().name("TestInterface")
.defineMethod("test",String.class, Modifier.PUBLIC | Modifier.STATIC)
.intercept(FixedValue.value("Hello")).make()
.load(this.getClass().getClassLoader(),
new AndroidClassLoadingStrategy.Wrapping(context.getCacheDir())).getLoaded();
Object o = c.getMethod("test").invoke(c);
After running this in Android I get the error Cannot define non-virtual method test for a pre-java 8 interface type.
I actually checked and from Android version 24 and later Interfaces with static methods is supported but I think the issue is that when you query Android for 'java.version' property it returns 0 which makes byte-buddy think we are an older version of JVM.

Byte Buddy validates against the Java version that is inferred from the platform context and on Android, this is indeed too strict. You can disable validation by setting:
new ByteBuddy().with(TypeValidation.DISABLED)

Related

Read assembly version of class library Project from .netCore web app project

I have 4 web applications based on .net core. all of them call a business logic layer (class library)
i want my version to get updated on all 4 web applications.
I have tried to make a static class on my business logic layer. and on this class i have a property that gets the version as the following:
Assembly.GetEnteryAssembly().GetName().Version
i tried to call this static class from one of the applications, sadly it brings the version of the web application instead of the class library version.
I want a code that always brings me the version of class library regardless from where it is called.
You can use Assembly.GetAssembly(typeof(YourClass)), being YourClass any class within desired assembly.
You can use typeof(Startup).Assembly.GetName().Version.ToString()

Tapestry hot swap in Intellij is not working for changes done in java class

In Tapestry(5.0) when ever I try to recompile my changes in java class i get a popup saying
Hot Swap Failed
abc.xyz : hierarchy changes not implemented
abc.xyz : Operation not supported by the VM
AFAIK this should be working and because of this I end up restarting the debug session which takes quite a bit of time.
Any help with this ?
You see this warning, because IntelliJ is failing to hot swap the classes, because, as the message says: VM doesn't support this operation for your changes.
What Tapestry is doing is actually not a hot swap, it's called "Live Class Reloading".
In short: instead of updating existing classes and objects inside VM (what hot swap is doing), Tapestry throws old classes away with all their state, and loads/initialises them again using a custom class loader. It can only do this for its managed classes: page/component/mixin classes and IoC service implementations that are registered using service interface. Everything else can only be reloaded with a hot swap if it's implemented by a VM.
You can read more details about Live Class Reloading in official documentation .

Javassist NotFoundException when getting java.io.Serializable with JDK9

I have the following code:
private static CtClass resolveCtClass(String clazz) throws NotFoundException {
ClassPool pool = ClassPool.getDefault();
return pool.get( clazz );
}
When running under JDK8, if this method is called using java.io.Serializable, it works, but when running under the JDK9 environment, it throws the NotFoundException.
Is there something I overlooked here?
This does no longer happen with the current EA builds of Java 9. Class files are now always locatable even if they are encapsulated in a module.
This is a consequence of Java 9's module encapsulation where non-exported resources are no longer available via the ClassLoader API. Under the covers, Javassist calls
ClassLoader.getSystemClassLoader().findResource("java/io/Serializable.class");
to get hold of the class file for Serializable. It then parses this class file and represents the information similarly to the Java reflection API but without loading the class such that it can be edited prior to loading it.
Until Java 8, this class file was accessible as most class loaders rely on looking up a class file before loading it such that the above call returned a URL pointing to the file. Since Java 9, resources of named modules are only available via the new API method findResource(String, String) where the second arguments names the module of that class.
The short answer is: Javassist does no longer work with Java 9 and none of its dependant projects will. This is a known issue with the current Java 9 implementation and will hopefully be fixed prior to release.
(I never used Javassist so I'm just shooting in the dark, here...)
The documentation of ClassPool says:
If get() is called on this object, it searches various sources represented by ClassPath to find a class file and then it creates a CtClass object representing that class file.
This seems to be bound to the concept of the class path. Looking at ClassPath and CtClass supports that assumption.
If that is the case, then Javassist might just not be fit to look into JDK 9's brand new modules.
If my guess is correct, you should not be able to get any JDK class from the pool. This should be easily verifiable.

Intellisense in VS 2012 RC not working for SignalR classes

I have imported SignalR Nuget package and SignalR sample is working well in my project. But even after having all required using statements I can't get the intellisense working for the classes in SignalR (like Hub class).
The hubs proxy is dynamically generated at runtime, so you won't get any intellisense for it.
You can use Hubify.exe (see Hubify-section on http://weblogs.asp.net/davidfowler/archive/2012/06/10/signalr-0-5-1-released.aspx ) to generate a static javascript-file.
Or you can create your own T4-Template that does the same thing. See: https://github.com/SignalR/SignalR/issues/106
Update:
Regarding intellisense for C#
You won't get intellisense for Clients and Caller, since they are dynamic.
Absence of compile-time type checking leads to the absence of IntelliSense as well. Because the C# compiler doesn't know the type of the object, it can't enumerate its properties and methods. This problem might be solved with additional type inference, as is done in the IronPython tools for Visual Studio, but for now C# doesn't provide it.
http://visualstudiomagazine.com/articles/2011/02/01/understanding-the-dynamic-keyword-in-c4.aspx
public class Chat : Hub
{
public void Send(string message)
{
// No intellisense for addMessage, sorry
Clients.addMessage(message);
}
}
look at the SignalR documentation here
the Hub.Caller and Clients are dynamic in nature.
dynamic is a new keyword added in .Net 4 and dosent support compile time checking so you cannot get intellisense for dynamic objects. all the dynamic objects are checked at runtime only. so even if you your self create a dynamic object like
dynamic d = new ExpandoObject();
and try to do this "d.". you wont get any intellisense because the framework dosent know whats all is present in the dynamic object. and will be discovered only at runtime.

How to make iPhone universal binary for iOS4 and iOS3?

It is possible to make universal binary for os 2.x and 3.x, you can see sample code for MFMailComposer But how to make it for iOS4 and iOS3 and XCode 3.2.3?
yes, there's some documentation on the process but if you want to instantiate a class which might not be present, you must test first.
Using NSClassFromString returns null if you're running on 3.x without the class, and returns a class you can use to allocate a new instance if the class exists while running on a later OS. In this way, you can test and fallback to 3.x code and make use of 4.x classes and features if available.
Be sure you compile against newer (4.x) libraries while you also set your Target OS to be lower (3.x) so you can cast a new class in your code without compile time warning.
If you want to use a new API or support a change in API, you might test for method presence using respondsToSelector and optionally fire the method via performSelector etc.
There are many different cases, but the idea revolves around setting a the target OS and testing runtime events in order to fallback or avoid features only available in a later OS'
For instance, you might check for UILocalNotification class's existence and if it is available, you put a button on the toolbar and if it doesn't exist, you don't - thus altogether avoiding code which would crash at runtime.