GWT cannot find *native method* from "User Module" at compile time - java

I am trying to integrate my GWT code with Guice/GIN (as it needs different config on the client, in the JVM (shared code), and when running tests). I am now getting a strange error about not finding a method when compiling:
[INFO] com.google.gwt.dev.jjs.InternalCompilerException: Unexpected error during visit.
...
[INFO] Caused by: java.lang.UnsatisfiedLinkError: com.google.gwt.user.client.Timer.createCallback(Lcom/google/gwt/user/client/Timer;I)Lcom/google/gwt/core/client/JavaScriptObject;
[INFO] at com.google.gwt.user.client.Timer.createCallback(Native Method)
[INFO] at com.google.gwt.user.client.Timer.scheduleRepeating(Timer.java:121)
[INFO] at ...
com.google.gwt.user.client.Timer resides in the User module, and Timer.scheduleRepeating() is written in Java, and delegates to Timer.createCallback(), which is a "native" (JavaScript) method. So the compiler finds Timer itself, and Timer.scheduleRepeating(), but not the native method.
What could cause this? I did not have this issue before trying to use GIN.
EDIT: Since others seem to see different code, here is what I see when looking at com.google.gwt.user.client.Timer:
...
private static native JavaScriptObject createCallback(Timer timer, int cancelCounter) /*-{
return $entry(function() { timer.#com.google.gwt.user.client.Timer::fire(I)(cancelCounter); });
}-*/;
...
public void scheduleRepeating(int periodMillis) {
if (periodMillis <= 0) {
throw new IllegalArgumentException("must be positive");
}
if (isRunning()) {
cancel();
}
isRepeating = true;
timerId = Impl.setInterval(createCallback(this, cancelCounter), periodMillis);
}
...

You have added a new dependencies in the project.
Please clean the project and re-compile it again.
Remove gwt-unitCache and other auto generated stubs also as shown in below screenshot

OK, I worked it out. In the GIN module, I am injecting some piece of code that needed to create a GWT Timer. And the problem was, that GIN execute the module at compile time. Of course, at compile time, the GWT Timer "native code" was not available, since that happened in the JVM itself.
So I just tried to catch the UnsatisfiedLinkError and ignore it. But that die not work out directly either, because UnsatisfiedLinkError is not available in GWT, so I just caught "Error" instead, and checked the class name. Then it all worked. But not before I discovered, to my dismay, that I cannot override a "provideXXX()" method on a GIN module (why?). Also, even if it is allowed for a GIN module to be abstract, GIN still requires a public no-arg constructor (which GIN will never call, because an abstract class cannot be instantiated!).

Related

How to make an interface a compile-only dependency when loading its implementation dynamically

Consider the following interface
// src/MyInterface.java
interface MyInterface {
public void quack();
}
which is used in the following application dynamically; i.e. its implementation is loaded dynamically—for demonstration purposes we'll just use the implementing class' name to determine which implementation to load.
// src/Main.java
class Main {
public static void main(String[] args) {
try {
MyInterface obj = (MyInterface) Class.forName("Implementation")
.getDeclaredConstructor()
.newInstance();
obj.quack();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
The following implementation of the interface is available:
// src/Implementation.java
class Implementation implements MyInterface {
public void quack() {
System.out.println("This is a sample implementation!");
}
}
As I would intuitively think, MyInterface provides information that is only relevant at compile-time, such as which methods can be invoked on objects that implement it, but it shouldn't be needed at runtime, since it doesn't provide any "executable code". But this is not the case: if I try to run the compiled Main.class without MyInterface.class, it complains:
$ javac -d bin/ src/*
$ rm bin/MyInterface.class
$ java -cp bin/ Main
Exception in thread "main" java.lang.NoClassDefFoundError: MyInterface
[...]
I guess it makes sense because it needs access to the MyInterface's Class object to perform the cast to MyInterface, so it needs to load MyInterface. But I feel there should be a way to make it a compile-time only dependency. How?
Some context
This question arose when I learned that there can be compile-time only dependencies, an example of which is the servlet api. I read that when compiling servlet code, you need to have the servlet-api (in Tomcat's case) jar, but at runtime it is not needed because the server provides an implementation. Since I didn't understand exactly how that could work, I tried setting up the little experiment above. Did I misunderstand what that means?
Edit: this Gradle page mentions that a compile-time only dependency could be
Dependencies whose API is required at compile time but whose implementation is to be provided by a consuming library, application or runtime environment.
What would be an example for that? I find that sentence a bit confusing, because it seems to imply that the API is not needed at runtime, and only the implementation is. From the answers, I gather that's not possible, right? (Unless somehow implementing a custom classloader?)
Yes, looks like you misunderstood example with servlet-api.jar. You need it in your project as a compile time dependency because Tomcat comes itself with that jar and that jar will be added to runtime classpath by Tomcat.
if you use classes/interfaces in your code they should be somehow added to classpath since your code depends on them.
And starting Java 8 interfaces can have default implementations for methods ("executable code") and interfaces also can have constants.
Maybe it is possible to run application without interface declaration but in that case you need to develop your custom Classloader which will check for interface implementation and load it instead of interface itself.
Did I misunderstand what that means?
Yes.
You're talking about "provided" dependencies (at least, that's what Maven calls them). Such a dependency still must be present on the classpath/modulepath at both compile-time and runtime. However, you don't have to include the provided dependency with your application when deploying your application, because the target container/framework already includes the dependency.

Reflection Method to get com.android.server.notification.NotificationManagerService methods

I tried to access NotificationManagerService class which is in android.service.notification package using reflection method. I tried this to clear Notifications of other apps which has FLAG_NO_CLEAR
Here is the snippet,
try {
Class<?> c = Class.forName("com.android.server.notification.NotificationManagerService");
Constructor<?> constructor = c.getDeclaredConstructor();
constructor.setAccessible(true);
Object o = constructor.newInstance();
Method method = c.getDeclaredMethod("cancelAllNotificationsInt",
new Class[]{String.class,int.class,int.class,boolean.class});
method.setAccessible(true);
Object r = method.invoke(o,sbn.getPackageName(), Notification.FLAG_NO_CLEAR,0,true);
if((boolean)r)
Log.d("Working","yes");
} catch (Exception e) {
e.printStackTrace();
}
But I am getting exception,
java.lang.ClassNotFoundException:
com.android.server.notification.NotificationManagerService
The class exist and here is the link from where I confirmed it.
Help me!!! Thanks in advance
Using Reflection and trying to assess Framework class is not a good way of implementing a feature. This is a bad practice.
From Android 4.3 onward, you can now cancel notifications from any apps.
You just need to implement the NotificationListenerService
you could cancel the notification of any app using the method NotificationListenerService.cancelNotification(String pkg, String tag, int id)
you could refer this sample notification-listener-service-example
I am not very particular with android development but this is usually environment issue. Sometimes, the actual class is not there in the library depending on how you have included your dependencies.
If at your development / IDE, you already encounter the problem, go to your external libraries imported by your gradle (or maven). Drill down to com.android.server.notification.NotificationManagerService if it is there. Or debug it and see if Class<?> c is null.
If it happened on the deployed version, open the file, go to the imported classes and drill down to the actual class if it is there or not.
If this library is provided by the environment you deploy - might be (1) overwritten by other library conflict or (2) version issue

java.lang.NoClassDefFoundError only in particular conditions

My problem is that when class B tries to use A.check() my execution stops due to a java.lang.NoClassDefFoundError.
So here is my class configuration. NB: the classes are in the same packages and I have already checked that the A.class file is placed where it should be.
public class A{
// vars
// declare some public method
public synchronized static boolean check(){
//do stuff, log some info and return boolean
}
}
public class B implements Runnable{
public void run() {
A.check();
}
}
And here is my stacktrace:
java.lang.NoClassDefFoundError:
org/mypackage/A
at org/mypackage.B.run()
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException:
org/mypackage.B
at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
The project is really big and class A is used lots of times before this call without any problem, so i don't think that is something relative to the classpath. Note that this is part of the last call of the software that should close up everything.
Moreover, I have two maven goals: the first one execute the questioned code without any problem, instead the second rise this error every time.
So I have solved my problem and I post here the solution so maybe can be useful for someone else.
First of all the error: java.lang.NoClassDefFoundError
This error is really different from ClassNotFoundException and this is where I'have lost a lot of time.
NoClassDefFoundError in Java is raised when JVM is not able to locate a particular class at runtime which was available at compile time. For example, if we have a method call from a class accessing any member of a Class and that class is not available during runtime then JVM will throw NoClassDefFoundError. It’s important to understand that this is different than ClassNotFoundException which comes while trying to load a class at run-time only and the name was provided during runtime, not on compile time. Many Java developer mingles this two Error and gets confused. Here I quote a really useful blog that I uesd.
So in a shorter way NoClassDefFoundError comes if a class was present during compile time but not available in java classpath during runtime.
But even with those information the problem was still there until I found the mystery: one of the reason that can place the class in a state that can be compiled but not located at runtime is that if you have static initialization that fail (e.g. in my class I had as field a static variable instantiated badly).
So remember to check for you initialization phase if you have static variables in your class this could be the reason of your java.lang.NoClassDefFoundError.
By the way I don't get why this kind of error is not raising some more meaninful errors for example java.lang.ExceptionInInitializerError or something like that.
Try to debug maven execution by running: mvn -X <your_goals>
It would be useful to see your POM file.
If you are working with spring mvc and if you made bean entry in dispatche-servlet.xml for Controller class.
Example :
<bean id="MyClass" class="com.aaps.myfolder.MyClass">
<property name="methodNameResolver">
<ref bean="methodNameResolver" />
</property>
</bean>
And if MyClass.java is not compiled & if no class file is generated in classes folder of your project folder then it wil show java.lang.NoClassDefFoundError.
So check whether the MyClass.class is created or not in classes folder if you are working with spring mvc.
Does Class A have anything that is done in a static block. You can get this exception even if a class is being loaded and static blocks fails for any reason reason. try to put in logging to see if something like this is happening.

Mockito fails in Maven but succeeds in Eclipse

We have a test wich fails when executed in Maven, but succeeds in Eclipse.
Basically the problem is, that when executed with Maven Mockito fails to mock a method which comes from a superclass from another maven module with package private modifier.
Questions
Why is this so?
Is this a known bug? If not where to file it? surefire, mockito ...?
how to fix it?
I have found a description of a similar problem, with the recommended fix to use surefire-2.7.1 instead of 2.7.0 but we are already on 2.10 (and also see the problem in 2.16)
Obviously the simplest solution would be to make the BaseClass public, but we can't do it, since it is not under our control.
Another alternative would be to overwrite close in MockedClass, which would be ugly but possible.
The error message is
failsCallingOriginalMethod(ModifierTest) Time elapsed: 0.156 sec <<< ERROR!
java.lang.RuntimeException: must not have called me
Relevant Code
The real code is not in the default package, but all code is in the same package; import statements removed for brevity.
Maven Module 1
public class ModifierTest
{
#Test
public void failsCallingOriginalMethod()
{
MockedClass mock = Mockito.mock(MockedClass.class);
doNothing().when(mock).close();
}
}
Maven Module 2
public class MockedClass extends BaseClass
{
}
class BaseClass
{
public void close()
{
throw new RuntimeException("must not have called me");
}
}
Versions of stuff involved
Maven Version 3.0.5 (can't change that due to other bugs)
Oracle JDK 1.6.0_20 (reproducable with IBM JDK 1.5)
Mockito 1.95
surefire plugin 2.10 (reproducable with 2.16)
Do you have control over MockedClass?
If so, you could consider adding a delegating method in MockedClass:
public void close() {
super.close();
}
This doesn't solve the issue, but it's a quick workaround.

AspectJ Load time weaver doesn't detect all classes

I am using Spring's declarative transactions (the #Transactional annotation) in "aspectj" mode. It works in most cases exactly like it should, but for one it doesn't. We can call it Lang (because that's what it's actually called).
I have been able to pinpoint the problem to the load time weaver. By turning on debug and verbose logging in aop.xml, it lists all classes being woven. The problematic class Lang is indeed not mentioned in the logs at all.
Then I put a breakpoint at the top of Lang, causing Eclipse to suspend the thread when the Lang class is loaded. This breakpoint is hit while the LTW weaving other classes! So I am guessing it either tries to weave Lang and fails and doesn't output that, or some other class has a reference that forces it to load Lang before it actually gets a chance to weave it.
I am unsure however how to continue to debug this, since I am not able to reproduce it in smaller scale. Any suggestions on how to go on?
Update: Other clues are also welcome. For example, how does the LTW actually work? There appears to be a lot of magic happening. Are there any options to get even more debug output from the LTW? I currently have:
<weaver options="-XnoInline -Xreweavable -verbose -debug -showWeaveInfo">
I forgot tom mention it before: spring-agent is being used to allow LTW, i.e., the InstrumentationLoadTimeWeaver.
Based on the suggestions of Andy Clement I decided to inspect whether the AspectJ transformer is ever even passed the class. I put a breakpoint in ClassPreProcessorAgent.transform(..), and it seems that the Lang class never even reaches that method, despite it being loaded by the same class loader as other classes (an instance of Jetty's WebAppClassLoader).
I then went on to put a breakpoint in InstrumentationLoadTimeWeaver$FilteringClassFileTransformer.transform(..). Not even that one is hit for Lang. And I believe that method should be invoked for all loaded classes, regardless of what class loader they are using. This is starting to look like:
A problem with my debugging. Possibly Lang is not loaded at the time when Eclipse reports it is
Java bug? Far-fetched, but I suppose it does happen.
Next clue: I turned on -verbose:class and it appears as if Lang is being loaded prematurely - probably before the transformer is added to Instrumentation. Oddly, my Eclipse breakpoint does not catch this loading.
This means that Spring is new suspect. there appears to be some processing in ConfigurationClassPostProcessor that loads classes to inspect them. This could be related to my problem.
These lines in ConfigurationClassBeanDefinitionReader causes the Lang class to be read:
else if (metadata.isAnnotated(Component.class.getName()) ||
metadata.hasAnnotatedMethods(Bean.class.getName())) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
return true;
}
In particular, metadata.hasAnnotatedMethods() calls getDeclaredMethods() on the class, which loads all parameter classes of all methods in that class. I am guessing that this might not be the end of the problem though, because I think the classes are supposed to be unloaded. Could the JVM be caching the class instance for unknowable reasons?
OK, I have solved the problem. Essentially, it is a Spring problem in conjunction with some custom extensions. If anyone comes across something similar, I will try to explain step by step what is happening.
First of all, we have a custom BeanDefintionParser in our project. This class had the following definition:
private static class ControllerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
protected Class<?> getBeanClass(Element element) {
try {
return Class.forName(element.getAttribute("class"));
} catch (ClassNotFoundException e) {
throw new RuntimeException("Class " + element.getAttribute("class") + "not found.", e);
}
}
// code to parse XML omitted for brevity
}
Now, the problem occurs after all bean definition have been read and BeanDefinitionRegistryPostProcessor begins to kick in. At this stage, a class called ConfigurationClassPostProcessor starts looking through all bean definitions, to search for bean classes annotated with #Configuration or that have methods with #Bean.
In the process of reading annotations for a bean, it uses the AnnotationMetadata interface. For most regular beans, a subclass called AnnotationMetadataVisitor is used. However, when parsing the bean definitions, if you have overriden the getBeanClass() method to return a class instance, like we had, instead a StandardAnnotationMetadata instance is used. When StandardAnnotationMetadata.hasAnnotatedMethods(..) is invoked, it calls Class.getDeclaredMethods(), which in turn causes the class loader to load all classes used as parameters in that class. Classes loaded this way are not correctly unloaded, and thus never weaved, since this happens before the AspectJ transformer registered.
Now, my problem was that I had a class like so:
public class Something {
private Lang lang;
public void setLang(Lang lang) {
this.lang = lang;
}
}
Then, I had a bean of class Something that was parsed using our custom ControllerBeanDefinitionParser. This triggered the wrong annotation detection procedure, which triggered unexpected class loading, which meant that AspectJ never got a chance to weave Lang.
The solution was to not override getBeanClass(..), but instead override getBeanClassName(..), which according to the documentation is preferable:
private static class ControllerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
protected String getBeanClassName(Element element) {
return element.getAttribute("class");
}
// code to parse XML omitted for brevity
}
Lesson of the day: Do not override getBeanClass unless you really mean it. Actually, don't try to write your own BeanDefinitionParser unless you know what you're doing.
Fin.
If your class is not mentioned in the -verbose/-debug output, that suggests to me it is not being loaded by the loader you think it is. Can you be 100% sure that 'Lang' isn't on the classpath of a classloader higher in the hierarchy? Which classloader is loading Lang at the point in time when you trigger your breakpoint?
Also, you don't mention AspectJ version - if you are on 1.6.7 that had issues with ltw for anything but a trivial aop.xml. You should be on 1.6.8 or 1.6.9.
How does ltw actually work?
Put simply, an AspectJ weaver is created for each classloader that may want to weave code. AspectJ is asked if it wants to modify the bytes for a class before it is defined to the VM. AspectJ looks at any aop.xml files it can 'see' (as resources) through the classloader in question and uses them to configure itself. Once configured it weaves the aspects as specified, taking into account all include/exclude clauses.
Andy Clement
AspectJ Project Lead
Option 1) Aspect J is open source. Crack it open and see what is going on.
Option 2) Rename your class to Bang, see if it starts working
I would not be surprised if there is hard coding to skip "lang' in there, though I can't say why.
Edit -
Seeing code like this in the source
if (superclassnameIndex > 0) { // May be zero -> class is java.lang.Object
superclassname = cpool.getConstantString(superclassnameIndex, Constants.CONSTANT_Class);
superclassname = Utility.compactClassName(superclassname, false);
} else {
superclassname = "java.lang.Object";
}
Looks like they are trying to skip weaving of java.lang.stuff.... don't see anything for just "lang" but it may be there (or a bug)

Categories