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.
Related
Problem explanation
I have recently been trying to use Apache Jena with Java (rather than on the command line). I wrote a simple script to convert read and write differetn RDF format types, as so
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.query.Dataset;
import org.apache.jena.riot.Lang;
public class Go_NT
{
public static void main(String[] args)
{
Dataset dataset = RDFDataMgr.loadDataset("triail.nq");
RDFDataMgr.write(System.out, dataset, Lang.NTRIPLES);
}
}
triail.nq is a test nquads file containing 81 quads.
I invoked it as so:
javac -cp "/mnt/e/Tráchtas/apache-jena-3.17.0/lib/*" Go_NT.java
java Go_NT
It compiles without error, but when I run it, it returns an error
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/jena/riot/RDFDataMgr
at Go_NT.main(Go_NT.java:9)
Caused by: java.lang.ClassNotFoundException: org.apache.jena.riot.RDFDataMgr
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 1 more
What I have tried
I have looked around and seen that this error occurs almost always because a necessary .jar file is not included, so a class referenced by the code cannot be loaded. The solution to these other issues was to include all of /apache-jena-3.17.0/lib/* . Oddly enough, that has not worked for me--I do include all of the contents of lib/ in my classpath, but I am still seeing the error.
System notes
I am running Jena 3.17.0, using the default Linux binaries available here (https://jena.apache.org/download/index.cgi). I have not added or removed any other Jena modules.
I am running this in the Windows Subsystem for Linux (version 2) with Ubuntu 20.04.
If any of you have any insight into what could be causing this, I would greatly appreciate it!
Based on the comment by vvs, the link https://howtodoinjava.com/java-examples/set-classpath-command-line/ helped out a lot. There were 2 issues: I needed to include the classpath in the java command, not just javac. I also needed to include the current directory where the output of javac would be.
I fixed this by setting the CLASSPATH variable, and then adding all the needed directories to that. (You could also do this by adding the classpath into the -cp argument). Note that the : separates different directories.
In short, here is what I did:
export CLASSPATH=/mnt/e/Tráchtas/apache-jena-3.17.0/lib/*:.
javac Go_NT.java
java Go_NT
Note that you need to re-assign CLASSPATH each time you open a new terminal.
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?
Hi All java Experts!
When I tried a little example of acm library
import acm.program.*;
class prog extends ConsoleProgram {
public void run() {
int number = readInt("?");
println("You entered: " number);
}
}
It compiled successfully.
I used commandline like this:
javac -cp acm.jar; main.java
java -cp acm.jar; prog
But I got this error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: acm.util.DOSCommandLi
ne.getLine()Ljava/lang/String;
at acm.util.DOSCommandLine.getLine(Native Method)
at acm.util.DOSCommandLine.getCommandLine(JTFTools.java:1627)
at acm.util.JTFTools.getCommandLine(JTFTools.java:439)
at acm.util.JTFTools.getMainClass(JTFTools.java:464)
at acm.program.Program.main(Program.java:1320)
What does it mean... I think the JDK version problem.... however I am using JDK 'jdk1.7.0_79'
In my opinion It is throwing exception only for this JDK version. Request to try you and give feedback.
Thanks...
Solved!
It doesn't require any native library...
What I had to do was to Use main entry as:
public static void main(String[] args) {
new prog().start(args);
}
Adding after 'run' method it works now. Note: this line 'new prog().start(args);'
This solution found here:
http://www.dreamincode.net/forums/topic/240789-acmjar-package-problem-class-wasnt-find-in-project/
Thanks Choppy
But it took me considerable time Hushhhhh.....
UnsatisfiedLinkError at Native Method means that there is no native library (for windows it would be dll) loaded which could be called for your acm.util.DOSCommandLine.getLine() method.
With your library there should be native packages, which will contain native libraries for your system architecture. You have to put one of these into your classpath folder.
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)
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