I'd would like to examine a private method of an Android Activity by executing it within the Activity's public static void main(String[] args) method which I created.
I use Eclipse ADT and my naive approach of running the Activity as a Java application resulted in:
A fatal error has been detected by the Java Runtime Environment:
Internal Error (classFileParser.cpp:3174), pid=2936, tid=2980
Error: ShouldNotReachHere()
So I looked at the Run Configuration and found out that Android 3.1 is the sole entry in the Bootstrap Entries section of Classpath. I managed to configure the Build Path of the project so that the JRE is in the Bootstrap Entries too. Then I removed the Android 3.1 entry and added android.jar to User Entries.
The result of executing the Run Configuration is a RuntimeException:
Exception in thread "main" java.lang.RuntimeException: Stub!
at android.content.Context.(Context.java:4)
An alternative of executing some tests would be to fire up a JUnit test. But in the case of a private method this is cumbersome.
Is there a way to successfully run the main method of an Android Activity class?
There is another option for the problem at hand, if the private method - which should be examined through the execution of a main method - can be extracted to another class. This of course means that the method suddenly became at least protected.
But if the method is definded within a class that does not derive from android.app.Activity a main method can be defined. You only have to adjust the Run Configuration in Eclipse.
Run the class with Run as Java Application. This generates a new Run Configuration named like the class
Edit the newly creaded Run Configuration
Delete the Android library from Bootstrap Entries in the Classpath tab
Add JRE 6 or so to the build path of the project
Add this JRE to the Bootstrap Entries in the Classpath tab
Add android.jar, which resides in the platforms directory of the Android SDK in User Entries in the Classpath tab
Activity is very important from Android's point of view, Activity's lifecycle are collections of few methods which are handled by OS through out the activities' life.
public void onCreate(Bundle savedBunldeInstance)
is called as soon as the App is launched creating the activity. This is the entry point of an application in android. You must have the emulator or physical device for running Android app, Here the file is compiled 2 times, once by java compiler then by dalvik compiler.
DVM (Dalvik Virtual Machine) is located on the Android device (EMULATOR OR PHYSICAL), this is the reason why we need emulator or physical device to run it..and onCreate is the entry point for it.
On your request I am editing this post with an additional piece of information. The lines below are abstracted from http://developer.android.com/
Android applications don't have a single entry point.
(there's no main() function, for example).
for further details click this :
http://developer.android.com/guide/topics/fundamentals.html
The main method isn't the entry point in Android like in Java. You wanna override the
public void onCreate(Bundle savedBunldeInstance) method.
Related
I created an Android library that was originally coded with Java and it outputs an .aar file that I use in some of my projects.
When I include this lib in a project (an Android project created with Kotlin) and I decide to debug the code in this project, when the debugger reaches a line containing a library's class, it successfully steps into the class and I can see the source code of the class while I'm debugging it. I can continue the debug line by line inside the lib's class and everything works as expected.
However, I recently decided to convert this library to Kotlin but now, when the debugger reaches one of the lib's class and I step into the class to continue debugging there, I can no longer see the entire source code. I can only see the method signatures, but without the method definitions. I see only things like:
public class ClassA {
public fun function1(): kotlin.Unit
public fun function2(): kotlin.Unit
public fun function3(): kotlin.Unit
}
I didn't do any else in the library's project settings. I simply converted the files from .java to .kt.
Here are some things that I tried so far to solve this problem:
I confirmed that I included Kotlin's standard lib in the dependencies list of the build.gradle file in the library.
I disabled ProGuard (it has never been a problem, but I removed it just in case).
I disabled code minification (it has never been a problem too, but at this point I'm willing to try anything).
Anyone has any idea why this is happening?
While debugging when it prompt "Choose Sources", Click on that option
and select the "main" folder of the library module from your local codebase of the library
Now try to debug (by choosing 'step into' option etc), the debugger should able to get the source code.
This material says on page 10 that it is possible to run a JavaFX app without writing main. I suppose there is some predefined main inside jfxrt.jar which looks for a class extending Application and runs it.
Is that so? How to do that?
I suppose there is some predefined main inside jfxrt.jar which looks for a class extending Application and runs it.
This isn't really what's meant by that comment, and isn't how it works. All it is saying is that the "main class" doesn't need to define a main(String[] args) method if it is a subclass of javafx.application.Application. From the Oracle tools documentation for java:
The java command can be used to launch a JavaFX application by loading a class that either has a main() method or that extends the javafx.application.Application. In the latter case, the launcher constructs an instance of the Application class, calls its init() method, and then calls the start(javafx.stage.Stage) method.
(My emphasis)
So if the class specified on the command line is a subclass of Application, this behavior is simply baked into the JVM executable. Note that you still have to specify the class that is to be run; it just doesn't need a main method if it is an Application subclass. (The JVM is not scanning the classpath for candidate classes to run, as you seem to be describing in the question.)
The class to be run can be specified on the command line (java com.mycompany.MyApp) or can be specified in a jar file manifest in the usual way.
This was added in JDK 8, iirc.
I'm having the following situation:
I want to extend the functionality of a given plugin A (I have it's source code and start it by running the project as an Eclipse Application which opens a new Eclipse IDE which provides the plugins functionality) with an plugin B I am writing.
My plugin does run when I run it as a Java Application. Let's assume it just prints Hello World in the console. What I want is that I can call the function which does that from plugin A.
What I did:
I added my plugin B to plugin As Required Plugin-Ins.
I create an instance of the class which implements the Hello World-print and call the function inside a method of plugin A (I also tried to make the method static and call it without creating an instance which resulted in exactly the same errors).
I created an Extension Point in plugin B and added it as an Extension in plugin A. I just set the ID and name in the Extension Point.
What happens:
When the instance of the class in plugin B should be created, the program crashes with this error:
java.lang.NoClassDefFoundError: de/name_of/plugin_b/package/ClassName
[...]
Caused by: java.lang.ClassNotFoundException: de.name_of.plugin_b.package.ClassName cannot be found by de.name_of.plugin_a.package_1.0.0.qualifier
I guess I'm missing something imporant - can someone help me out on what it is?
Edit 2:
I've just read that I have to add "." to the classpath. Seems like this solved the issue! Thanks for making me dig deeper into the manifest, greg!
I do get a different error now tho, which also seems to be connected to me making mistakes when creating the plugin as I do not get this error when I run plugin B as a Java Application.
java.lang.NoSuchMethodError: org.apache.lucene.store.FSDirectory.open(Ljava/nio/file/Path;)Lorg/apache/lucene/store/FSDirectory;
The problem is, tho, that this method does exists (see lucene API here).
As seen in the manifest, I added the lucene-jars to the dependencies of plugin B.
You need to include every package that other plugins use in the Export-Package section of your plugin. In the MANIFEST.MF editor this is on the 'Runtime' tab in the 'Exported Packages' section.
You don't need an extension point to make this work.
I am instrumenting Android applications using a helper class following the example for Java instrumentation in http://www.sable.mcgill.ca/soot/tutorial/profiler2/profiler2.html.
In my BodyTransformer, I have a static block to load MyCounter class
counterClass = Scene.v().loadClassAndSupport("MyCounter");
Since Soot.Main.main(args) that processes my args (in which I provide -android-jars) is not executed while it is loading MyCounter, Soot cannot find my android jar and gives the error:
Caused by: java.lang.RuntimeException: You are analyzing an Android application but did not define android.jar. Options -android-jars or -force-android-jar should be used.
at soot.Scene.defaultClassPath(Scene.java:455)
at soot.Scene.getSootClassPath(Scene.java:224)
at soot.SootResolver.<init>(SootResolver.java:81)
at soot.Singletons.soot_SootResolver(Singletons.java:802)
at soot.SootResolver.v(SootResolver.java:91)
at soot.Scene.loadClass(Scene.java:667)
at soot.Scene.loadClassAndSupport(Scene.java:653)
at MyBodyTransformer.<clinit>(MyBodyTransformer.java:26)
... 1 more
As a solution, I provided my command line arguments (android jars, soot classpath, prepend classpath and process directory) in my main class, before creating my BodyTransformer. Now, it works.
I would like to ask whether there is a more proper way to solve this problem.
loadClassAndSupport is nor sufficicient. Here is what you should do. In your analysis' main method, before you call Soot's main method add the following:
Scene.v().addBasicClass("MyCounter");
Then within your analysis simply use Scene.v().getSootClass("MyCounter").
A Java class made for video coding loads a DLL including C++ code
Unpacking debugging symbols for VideoSource.dll to \path
Checking for VideoSource.pdb...
Checking for videosource.pdb...
and then tries to instantiate a native (C++) class from that DLL:
// VideoSource() is implemented in C++ and wrapped with JNI,
// wrapper files were generated with SWIG
_videoProvider = new generated.VideoSource();
That works when the Java class is executed as a JUnit test (video data is extracted).
Same thing does not work when I launch the Java class as an OSGi service.
Essentially, the same code is executed. The DLL is still loaded successfully but the instantiation of the native (C++) class shown above now throws an exception:
java.lang.UnsatisfiedLinkError: generated.VideoSourceSWIGJNI.new_VideoSource()J
What is different when I launch the Java class as an OSGi service instead of executing it as a JUnit test? What can I do to make it work?
BACKGROUND
generated.VideoSource() is
public VideoSource() {
this(VideoSourceSWIGJNI.new_VideoSource(), true);
}
VideoSourceSWIGJNI.new_VideoSource() is
public final static native long new_VideoSource();
C++ implementation is
VideoSource::VideoSource() {
// init frame count
m_frame_cnt = 0;
[..]
}
Thanks, Puce, for pushing me a bit. After asking "would I have to try anything at all"? I got the answer relative quickly:
In order to resume sources (1, 2, 3, 4) with my own words:
When native code, e.g. .so or .dll libraries, shall be used in an OSGi bundle, corresponding libraries have to be declared in the bundle's manifest.
The manifest file may either be edited explicitely, as stated in mentioned sources, or implicitely via an appropriate plugin, e.g. apache felix, when using maven. Used plugin is configured in the POM file and will modify the manifest automatically.