There are a alot of questions about javah, but I couldnt find any solution for my issue for 3 day.
My java file work normally and no error.
I copied my java file "I2CInterface.java" to "jdk/bin" directory.
Then "javac I2CInterface.java" the I2CInterface.class created succesfully.
But "javah -jni I2CInterface" is not work the header file cant created. The error is "class not found" I try with classpath but not work. I set my environtmental and add path C:\Program Files\Java\jdk1.8.0\bin. No work.
That is interesting javah work on some class and it can create header. But on this class and some class not work.
The problem is about java file? My java file below.
package com.multitek.ipintercomflatunit;
public class I2CInterface {
private static native int i2cwrite(byte[] data);
private static native byte[] i2cread(int data_len);
public static int write(byte[] data) {
return(i2cwrite(data));
}
public static byte[] read(int data_len) {
return(i2cread(data_len));
}
static
{
System.loadLibrary("i2cinterface");
}
If the class is in a package, say xxx, the correct command line will be
javah xxx.I2CInterface
I copied my java file "I2CInterface.java" to "jdk/bin" directory
Why? There's no need to do that. Don't pollute the Java installation directory with your own stuff. Leave it where it was and compile it there. Adjust your PATH if necessary so you can execute the JDK tools.
Related
I wrote a Java program whose filename was (intentionally) different from the class I wrote inside the file. The javac command failed as expected on both CMD and WSL. The java command however worked and ran my print statement. I wrote the code intentionally this way so there is no way it was a previously compiled version of the code. The following code was written in a file called "explainJava.java" (notice the filename is different from the class name).
public class explain{
public static void main(String[] args) {
System.out.println("Java is weird");
}
}
I've had to google this myself, but I think I've found an explanation in this article.
According to that source as of Java 11 java is capable of compiling a single source file into memory.
What I conclude from that: When the file is compiled into memory and not written to disk it obviously cannot have a file name. If there is no filename there is no such thing as a wrong filename, therefore the code executes.
Please also note that the restriction of having to name a file like the public class within that file is more of a design decision to make work for the compiler easier/ faster. It is not a physical restriction so to speak. Have a look at the following thread for more details.
If you put this code:
public class explain {
public static void main(String[] args) {
System.out.println("Java is weird");
}
}
into a file named explainJava.java, and then compile it with this:
javac explainJava.java
you will get an error that correctly informs you that your filename ("explainJava") and the class defined inside that file ("explain") do not match:
explainJava.java:1: error: class explain is public, should be declared in a file named explain.java
public class explain{
^
1 error
If you run this command:
$ java explainJava.java
Java is weird
you see expected output, because you're skipping the explicit compilation step (that is, you aren't running javac first) and instead relying on behavior introduced in Java 11 that allows you to compile+run in a single step. Here's an explanation: Does the 'java' command compile Java programs?
So the answer is to either:
rename your file to match the class, so change the filename to "explain.java", or
rename the class to match the file, change public class explain to be public class explainJava
I am trying to create a JAR file for my two source codes Serial.java and DBaccess.java.
I am doing this as a learning exercise ,the classes do not do anything,they are dummy classes.
OS - Windows 10
JDK - GraalVM
Listing of my source code.(Serial.java)
public class Serial
{
void open()
{
System.out.println("Serial Port Opened - 0");
}
}
Listing of my source code.(DBaccess.java)
public class DBaccess
{
String DBname = "MySerialDB";
void write()
{
System.out.println("Data Written to DB - W");
}
void read()
{
System.out.println("Data Read from DB - R");
}
}
I have compiled them to .class files using javac
javac DBaccess.java
javac Serial.java
I created a folder
H:\myclass\com\mydomain\util
and manually copied the class files to util directory
and created a jar file myjar.jar of this format
H:\myclass>H:\graalvm\bin\jar tf myjar.jar
META-INF/
META-INF/MANIFEST.MF
com/
com/mydomain/
com/mydomain/util/
com/mydomain/util/DBaccess.class
com/mydomain/util/Serial.class
I want my source code JMainEntry.java to access the classes in the above jar file myjar.jar.
JMainEntry.java
//Main Class of the Program
import com.mydomain.util.*;
public class JMainEntry
{
public static void main (String[] Args)
{
Serial myS = new Serial();
myS.open();
DBaccess myDB = new DBaccess();
myDB.write();
myDB.read();
}
}
When i compile the code
H:\jar-compile>H:\graalvm\bin\javac -cp myjar.jar JMainEntry.java
I am getting the error
bad class file: myjar.jar(/com/mydomain/util/Serial.class)
class file contains wrong class: Serial
Please remove or make sure it appears in the correct subdirectory of the classpath.
I am not able to understand why javac is complaining like this,Can anyone help?
bad class file: myjar.jar(/com/mydomain/util/Serial.class)
Make sure you declare
package com.mydomain.util
at the top of all .java files in the directory com/mydomain/util, including Serial.java. To understand this better, read about packages.
I have following piece of code in one of my java program.
public class Solution {
public static void main(String[] args) {
System.out.print("Hello World");
}
public static void printOutput(String[] arr){
//Note: The semi colon is omitted intentionally.
System.out.print("Hello Incomplete World")
}
When I build it I get a compilation error but still it generates a .class file. when I run the .class file, it gives an output of "Hello World".
How is this possible ? I always believed a .class file having unresolved compilation problems will never be an executable one. Can anyone provide some information on that ?
What's probably happening here is that a successfully compiled class file already exists. When the Java compiler runs, it'll produce a .class file if it compiles a source file successfully, but it will not remove subsequent compilation fails.
You're assuming the compiler will clear out your old class files - it doesn't.
Check the modification date on your current .class file - you'll see that it's older than your compilation. That's because it was generated from working code, not from your current source file. If you delete this class file, then try to recompile, you'll see that a new class file is not created.
The class file you are running is from a previous compilation. Compile your program again and look at the time the class file was previously modified.
I have stuck in the class->header file for couple days!
I have tried on jni on Client by http://netbeans.org/kb/docs/cnd/beginning-jni-linux.html and http://ringlord.com/jni-howto.html. And it succeeded in return "hello JNI C++" from JNI's (.cpp)file. Here are my steps:
create native function and in client.java
clean &build this client.java on Netbeans IDE, then result a client.class file
javah –jni [package].[classname]
create a dynamic library C++ project as first reference does, and put client.h into source file, and put some hello code into (.cpp)file ---> It works!
However, I tried to do the same thing on the servlet side and it's not working
Servlet.java->Servlet.class : ok!
Servlet.class->Servlet.h: fail!!!!
Error : cannot access javax.servlet.GenericServlet
class file for javax.servlet.GenericServlet not found
The following are solutions I have found and tried so far,
check the package name
sudo gedit /etc/profile,sudo gedit .bashrc, sudo /etc/environment; add JAVA_HOME & CLASSPATH on them, and source them to update, then echo $JAVA_HOME, echo $CLASSPATH to verify
download servlet-api-6.0.14.jar & servlet-api-5.0.16.jar from http://www.jarfinder.com/index.php/java/info/javax.servlet.GenericServlet
,and add above two (.jar) by netbeans IDE->server->property->libraries->Add JAR
Please tell me how to figure it out this issue, thank you very much!!Btw, I am using hessianServlet
NativeWrapper.java (you run javah only on this class)
class NativeWrapper {
// either
static {
System.loadLibrary("MyOpenCVNative");
}
// or
public NativeWrapper() {
System.loadLibrary("MyOpenCVNative");
}
public native void callNative();
}
MyServlet.java
class MyServlet extends javax.servlet.GenericServlet {
private NativeWrapper nativeWrapper = new NativeWrapper();
public void someServletMethod() {
nativeWrapper.callNative();
}
}
I have two Java classes "giveMyOb" and "dataConn" declared in the same directory. Both are public classes. "giveMyOb" has a static method "getMine()". Inside dataConn, I called the static method as
giveMyOb.getMine();
When I try to compile dataConn.java, the following error is returned.
"Cannot find symbol
symbol: variable giveMyOb
location : class dataConn
giveMyOb.getMine(); "
It used to work earlier. But is not working now. Why is that?
Additional Information: JDK 1.6. Windows 7. 64 bit.
Update(30 days after the question): When compiled from Eclipse, the classes are referenced and it works. But the same won't work when compiling from command line. I was unable to figure out the reason and nothing logical comes to my mind!
javac -classpath . *.java
ought to create both .class files at the same time. It's more complicated by packages. I'm assuming you have none.
Learn the Sun Java coding conventions. You aren't following them with those class names. They should start with a capital letter.
Try this:
giveMyOb.java
public class giveMyOb {
public static String getMine() {
return "Yay, it works!";
}
}
dataConn.java
public class dataConn {
public static void main(String[] args) {
System.out.println(giveMyOb.getMine());
}
}
Then compile it all:
javac *.java
and run the main class:
java -cp . dataConn
// output: Yay, it works!
Note that Java's coding conventions recommend class names start with a capital.
If "it" still doesn't work, try removing the .class files manually then recompile again.