Is it possible to prepend bootclasspath for Dalvik VM on Android? - java

I'm experimenting with -Xbootclasspath in Java just for fun, and have added a test method int java.lang.Object#id(), just an instance-like identityHashCode method shortcut:
package java.lang;
public class Object {
public final int id() {
return System.identityHashCode(this);
}
// the original code goes here
}
The code above is compiled into a single-class JAR file, and the code below is compiled and dependent on the patch JAR file, thus the following code is legal:
public static void main(final String... args) {
System.out.println(new Object().id());
}
Running the sample application is quite easy prepending the bootstrap classes:
$ java -Xbootclasspath/p:patch.jar -cp app.jar test.Application
366712642
Works fine. Now, I wondering if it's possible to do the same trick on Android. So, the closest equivalent, I think, should be (from adb shell):
$ dalvikvm -Xbootclasspath:patch.jar -cp app.jar test.Application
java.lang.NoSuchMethodError: No virtual method id()I in class Ljava/lang/Object; or its super classes (declaration of 'java.lang.Object' appears in /syework/core-libart.jar)
at test.Application.main(Application.java:11)
Looks like prepending, but not working since it's saying that the java.lang.Object class is already defined in another location (probably the real path is /system/framework/core-libart.jar, at least it says similar, but that JAR is quite different -- then how after all?). I also saw a few examples with the $BOOTCLASSPATH variable, but none of them works for me for some reason.
Is it possible to run dalvikvm overriding the bootclass path somehow and where are the core classes are loaded from?
EDIT 1:
It probably would work, but Android Dalvik VM is really dependent on the zygote that all new Dalvik VM processes are forked from, thus the zygote does not run with an alternative boot classpath. At least, this is what I understood from this question: How to pass dalvik command line parameters through .apk?

Related

Java - Could not find or load main class Class01

Using Java 8
I have set my PATH as 'C:\Program Files\Java\jdk1.8.0_144\bin'
I also tried to set my CLASSPATH as 'C:\Program Files\Java\jre1.8.0_144\lib\rt.jar', though I read it is not neccesary.
From Class01.java I have no problem creating Class01.class
javac Class01.java -> created Class01.class
Still, when I try to run program
java Class01
I got message
Error: Could not find or load main class Class01
If anyone know, how to fix this, I appreciate every hint.
Btw. My program does nothing but printing Hello world, if it has something to do with my problem.
You will need to tell Java about the classpath where it should find your file. I think you are missing the classpath parameter in your java command (see below). Here is a simple example how you could create a java file, compile and run it:
A. Create File:
public class X {
public static void main(String[] args) {
System.out.println("Blah!");
}
}
B. Compile:
"%JAVA_HOME%\bin\javac" X.java
C. Run it using the `-classpath` parameter:
"%JAVA_HOME%\bin\java" -classpath . X
This will print out:
Blah!
Note that JAVA_HOME is a System variable in Windows which needs to point to the location of your Java Runtime Environment.

Loading native libraries in java

I have an eclipse project with two classes. The class "SomeClass1" has a native method:
SomeClass1
public class SomeClass1 {
static {
System.loadLibrary("libname"); // Load the native library.
}
public native void some_method(); // implemented in the library
// .... other non methods ....
}
The other class "SomeClass2" uses the native method of "SomeClass1". Like:
SomeClass2
public class SomeClass2{
public static void main(String[] args) {
SomeClass1 s = new SomeClass1();
s.some_method();
}
// ....other methods....
}
However when it calls that method it throws an error like this:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no libname in java.library.path
....
at java.lang.System.loadLibrary(Unknown Source)
at x.x.x.SomeClass1.<clinit>(SomeClass1.java:128)
at SomeClass2.main(SomeClass2.java:10)
I think the error has something to do with java not knowing where to look for the native library.
Question1
When I use: -Djava.library.path="C:\Users.....\libfolder\" as run argument in eclipse and print the value of: System.getProperty("java.library.path"); I see alot of directories printed but not the directory that I specified in the argument. What am I doing wrong?
Question2
When I do: System.loadLibrary("name"); do I need to call the library "name.so" or "libname.so"?
Question3
If the library would be found but was a 64 bit library while the platform it is loaded on is 32 bit, would it also give a unsatisfiedLinkError or would a different error be given?
Question4
Can I specify the path to the library relative to the projects folder or relative to the file in which the library is loaded?
Hope you are able to answer (some of) my questions.
Grtz Stefan
Question 1:
You should not add this as a run argument, but as a VM argument. It's not an argument for your program, but for the JVM.
Question 2:
(Also #IanRoberts ) : The System.loadLibrary(name) call will automatically derive the name of the actual library from the given name. That means that it will append ".dll" on windows, and use "lib" + name + ".so" on linux. Otherwise, loading a native lib would not be possible in a platform-independent way!
Question 3:
In general, the UnsatsfiedLinkError is distressingly common. It's in fact true to say: The UnsatisfiedLinkError does not tell you more than "Something is wrong". You can only hope for the actual error message to be more descriptive, and this would (fortunately) be the case if you had a 32/64bit mismatch - at least on windows:
Trying to load a 32bit lib on a 64bit system will cause the message: "Can't load IA 32-bit .dll on a AMD 64-bit platform"
Trying to load a 64bit lib on a 32bit system will cause the message: "... is not a valid Win32 application"
(I'm not sure about the message for other operating systems, though, but your message indicates that the library is just not found, and not that there's a problem with the library itself)
(Question 4: I'm rather sure that this is possible, but not absolutely sure (and can't try it out) at the moment. In general, the library must be in a path that is visible via the PATH environment variable, or via the java.library.path. In doubt, it should always work then the native libs are in the same directory as where you are starting your program from)

Getting java.lang.NoClassDefFoundError when trying the execute a java.class

I created the following class located in the MainJPrint.java file
import com.XXXXX.pdfPrint.PDFPrint;
public class MainJPrint
{
public static void main(String[] args)
{
//System.out.println("Hello World!");
print(".....");
}
public static String print (final String url)
{
Object rc = AccessController.doPrivileged(new java.security.PrivilegedAction()
{
public Object run()
{
...
}
}
}
}
In the same folder I have a jar archive jPrint.jar
I compile the class using the following command
>javac -classpath jPrint.jar MainJPrint.java
When I'm trying to execute resulted class file, I get this error:
>java MainJPrint
java.lang.NoClassDefFoundError: com/XXXXX/pdfPrint/PDFPrint
If I uncomment the Hello World line and comment the next line, the program runs fine.
I'm using j2sdk1.4.2 installed at C:\j2sdk1.4.2.
I do also have installed other java versions (at C:\Program Files\Java: jre 1.6.0_01, jre 1.6.0_02, j2re1.4.2, jre6, jre7, jdk1.7.0_03)
The PATH variable contains the C:\j2sdk1.4.2\bin path, however I think the java.exe is loaded from the upper version, but it shouldn't matter and I can call it like
>C:\j2sdk1.4.2\bin\java.exe MainJPrint
jPrint.jar is a third party archive and I need to create an applet which exposes a method so I can call it with javascript. I'm not a java developer, I'm having some little troubles and I'm really on an end here.
I tried other options like:
>java MainJPrint -cp .
>java MainJPrint -cp jPrint.jar
So how can I execute that class file which uses a class located in a separate archive?
To execute a class that depends on external JARs, you need to specify all elements of the classpath on the command line.
If you don't specify a classpath, Java automatically uses . (the current directory), which is why, if MainJPrint didn't depend on jPrint.jar, your invocation java MainJPrint would have worked.
But when you specify -cp jPrint.jar, Java does NOT automatically add the current directory to the classpath, which means that it then cannot find MainJPrint. You need to specify both. On Mac/*nix, the following invocation should work:
java -cp jPrint.jar:. MainJPrint
Or on Windows:
java -cp jPrint.jar;. MainJPrint

Statically Linking a GCJ Application on Ubuntu Natty

I'm trying to statically link a GCJ application and it looks like theres some misconfiguration somewhere. I'm just using the standard gcj installation on natty and I have both libgcj11 and libgcj11-dev installed.
My test application is:
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}
I do:
gcj -static-libgcj --main=HelloWorldApp HelloWorldApp.java
then i get the following error
/usr/bin/ld: cannot find -lgcj
collect2: ld returned 1 exit status
Anyone know how to fix this?
Distros generally do not ship libgcj.a. Static linking does not work extremely well with gcj, anyway, mostly because not all of the class dependencies can be found -- compiled-in resources and also the use of reflection in the core library cause things to go missing at link time, unless you take special care to link them in by hand.

Java virtual machine launch issue

HI All,
I got an issue, all of a sudden Java stopped working completely. I start getting error like "Could not create the virtual machine". There is no issue with the memory (it has 3GB RAM) and was working fine for over a 6 months in this system without any issue.
Here are some peculiar behaviors -
When I start eclipse I see Java virtual machine dialog box with error messages like
"Could not find main class org.eclipse......support.legacysystemproperties"
Eclipse is able to start(with above error), but while running the program, I get error like "Could not create Java Virtual Machine" in a dialog box and after I click OK on that dialog box, I see error like "unrecognized option -dfile.encoding=cp1252
I used text editor, wrote a class Test.java (without any package), compiled it (Edit #1:javac Test.java). But when I execute the program (Edit #1:java Test), I get the following error -
Exception in thread "main" java.lang.NoClassDefFoundError: test (wrong name: Test).
Edit #1:
Note : The compiled file, Test.class is successfully created in the directory. I did recheck the path and classpath environment variables. All seem to be correct.
Please note that there seems to be some issues with cases which affected the Java.
I did uninstall Java (all versions), re-installed, but nothing helped. Also, I did run CCleaner to clean registry, Malwarebytes' Anti-Malware, but none helped so far.
Appreciate if someone could help me to resolve the issue.
I did googled for this and found that some have experienced similar issues, but none of them have found solution yet other than some suggestion that re-installation of Windows OS itself, which I want to avoid it. I did system restore, but that failed for some other
reason.
Please note that am using Java for over 10 years. This is first time am having such issue. This is something to do with Windows Registry or some other system configuration, but I am not able to find out the exact problem.
Anyways awaiting some good suggestion.
EDIT: Okay, so it looks like the Java executable is getting the command line arguments lower-cased.
Step 1: Verify
You can double-check whether this affects all command line arguments by creating a class with a lower-case name which just dumps its arguments:
public class test {
public static void main(String[] args) {
for (String arg : args) {
System.out.println(arg);
}
}
}
Compile and run this with a variety of inputs.
Step 2: Check scope
Assuming step 1 confirms the problem, if you've got .NET installed you can see whether it affects that as well. Create a file Test.cs:
using System;
class Test
{
static void Main(string[] args)
{
foreach (string arg in args)
{
Console.WriteLine(arg);
}
}
}
Compile this with "csc Test.cs" having found csc in the .NET framework directory (e.g. in c:\Windows\Microsoft.NET\Framework\v4.0.30319 for .NET 4).
Run it like this:
Test foo BAR Baz
and see what happens
Step 3: If step 2 showed that the issue is limited to java.exe:
Check your path, and work out where you're actually running java.exe from
Try explicitly running java.exe from your JRE or JDK directory

Categories

Resources