I was working on book "Chapter-3-Communicating-with-Native-Code-Using-JNI.pdf". There when I tried to create header files using javah command I get the error:
Exception in thread "main" java.lang.IllegalArgumentException: Not a valid class name: ?classpath
I tried the instruction in terminal:
javah –classpath bin/classes com.example.hellojni.HelloJni
But i see that this is for Eclipse paths and I am using Android Studio. So I tried this:
..helloJni\app>javah -d jni –classpath build\intermediates\classes\arm7\debug com.example.hellojni.HelloJni
I have HelloJni.class file in "helloJni\app\build\intermediates\classes\arm7\debug\com\example\hellojni". I am still getting the same error and I am surprised that I couldn't find a direct solution on stackoverflow. Can you help me with this?
Did you copy the -classpath argument from somewhere? Your error message indicates that javah thinks -classpath is the class name. And as it shows ?classpath in the output, it seems the - is not what you think is, but some special character. Try typing -classpath yourself.
Edit: was curious. What you have instead of - is an –
Related
I've been trying to employ Kawa Scheme for developing Android project. I've found two repositories on GitHub: one called 'android-kawa', and another called 'KawaDroid'. They're both a bit dated (last updates were around 2012). In the case of 'android-kawa' I was able to reach the author, but he said he did't remeber enough to help me.
In the 'android-kawa' repo there's a bunch of scripts for setting up and working with the project. One of the scripts downloads the Kawa 1.13 tarball, applies some patches and then attempts to build it.
However, the build isn't supported in Termux, bevaise the config.guess script doesn't recognize the system. This issue can be easily resolved by downloading the latest versions of config.guess and config.sub.
Another problem is the format of the JVM bytecode. When I use the latest Java compiler, the generated bytecode contains (I believe) instructions for JVM8+, which aren't supported by the dx command. This isn't a problem if I run Java inside of Termux, because it installs the regular JVM, but if I want to include the Kawa jar in my APK (which is something that I want), then it becomes an obstacle.
This, again, can be resolved by forcing the Java version to 7 in javac. (But then, the compiler complsins that Java 1.7 is deprecated. I guess this is why the buildAPKs project uses ecj instead of javac)
Also, when I ./configure Kawa, I can pass it the path to the android.jar file (./configure --with-android=...). I have two android.jar files on my system:
~ $ locate android.jar
/data/data/com.termux/files/usr/share/aapt/android.jar
/data/data/com.termux/files/usr/share/java/android.jar
I don't know where they came from or how they differ between one another, but I've been prefering the second one.
So, when I have the kawa.jar available - and when I try to compile it with the command
~/android-kawa $ java -cp $(dirname $(locate android.jar |tail -n 1)) -jar kawa/kawa-1.13.jar -C KawaHello/src/kawa/android/hello.scm
I get the following error:
internal error while compiling KawaHello/src/kawa/android/hello.scm
java.lang.NoClassDefFoundError: android/view/View
at gnu.kawa.android.defs.<clinit>(defs.scm)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1155)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:42)
at java.base/jdk.internal.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:185)
at java.base/java.lang.reflect.Field.acquireFieldAccessor(Field.java:1132)
at java.base/java.lang.reflect.Field.getFieldAccessor(Field.java:1113)
at java.base/java.lang.reflect.Field.get(Field.java:425)
at gnu.expr.ModuleInfo.setupModuleExp(ModuleInfo.java:195)
at kawa.standard.require.importDefinitions(require.java:308)
at kawa.standard.require.scanForDefinitions(require.java:219)
at kawa.lang.Syntax.scanForm(Syntax.java:65)
at kawa.lang.Translator.scanForm(Translator.java:1120)
at gnu.kawa.lispexpr.LispLanguage.parse(LispLanguage.java:64)
at gnu.expr.Compilation.process(Compilation.java:1908)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:305)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:290)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:290)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:290)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:290)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:290)
at kawa.repl.compileFiles(repl.java:823)
at kawa.repl.processArgs(repl.java:444)
at kawa.repl.main(repl.java:869)
Caused by: java.lang.ClassNotFoundException: android.view.View
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ... 24 more
I have obviously tried it without the -cp argument (with the same effect). The android/view/View.class entry is present in the list returned by jar -tf android.jar.
How can I further investigate in the root cause of the problem, and most importantly, how can I solve it?
It turned out that I have invoked Java incorrectly, and that it didn't see the android.jar file. It helped to invoke the compiler in the following way:
~/android-kawa $ java -cp $(locate android.jar |tail -n 1):kawa/kawa-1.13.jar kawa.repl -C KawaHello/src/kawa/android/hello.scm
(the difference is that I only have one -cp argument with jar files separated by :, and that I explicitly give the kawa.repl class name)
In order to use NDK in my application, I included an external tool at Preferences -> Tools -> External Tools.
Here's what I did.
As I right-clicked a class and chose the external javah command to create a c class, it didn't work and left a following message.
Exception in thread "main" java.lang.IllegalArgumentException: Not a valid class name: /src/main/jni
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:129)
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:107)
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:64)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:503)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:329)
at com.sun.tools.javah.Main.main(Main.java:46)
Process finished with exit code 1
I properly created the jni folder under the main directory, and I'm still not clear why I keep getting this message.
Here's my development environment.
OS: OS X El Capitan
Android Studio: 2.2.2
I solved this problem by modifying the Parameters and Working Directory as follows.
Parameters: -classpath $Classpath$ -v -jni $FileClass$
Working Directory: $ProjectFileDir$/app/src/main/jni
The Point:
I want to call a C/C++ function from Java.
What I do:
1
I followed this direction. https://www.youtube.com/watch?v=0fEtrekNcOo
Just created Project, wrote below code and build it.
public native String HelloJNI();
static {
System.loadLibrary("HelloJNI");
}
2
javah -d jni -classpath /Applications/adt-bundle-mac-x86_64-20131030/sdk/platforms/android-19/android.jar;../../build/intermediates/classes/debug com.test.ndktest.MyActivity
The Problem:
I got this error message. "bash: ../../build/intermediates/classes/debug: is a directory"
I spent many time to find solutions.. Any help will be appreciated.
Thanks.
C/C++ will be used for obfuscation of my code. I will hide some API keys in C/C++ code.
I watched another video but I could not find any solutions.. https://www.youtube.com/watch?v=okLKfxfbz40
I use ant to unzip an apk file, but it occurred an error like this:
<unzip src="test.apk" dest="testdir" >
error message:
java.lang.RuntimeException: data starting at 0 is in unknown format
i googled it, and add attribute encoding="native-encoding" , it still error.
great thanks for any help!
ok,finally I wrote a custom ant task using java ziputil to unzip an apk files. It does work well.
I found a method for importing 3D models to Android's OpenGL on Stackoverflow here:
Is there a way to import a 3D model into Android?
Attempting to follow the instructions I copied the source and tried to compile the program. I got a massive number of errors, here is just a small sample:
/tmp/ccPavSpL.o:OFF-OpenGL_loader.cc:(.text+0xd): undefined reference to `std::basic_string<char,
std::char_traits<char>, std::allocator<char> >::size() const'
I think the problem was I wasn't passing in arguments to the program, so I tried passing arguments like so:
$ gcc OFF-OpenGL_loader.cc circle.off output.xml
(My .off file was in the same directory as the other source files and the output.xml was also in the same file.)
I got these errors
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld:circle.off: file format not recognized;
treating as linker script
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld:circle.off:2: syntax error
collect2: ld returned 1 exit status
Anyway so I have a feeling I wasn't supposed to have an output.xml file but when I didn't have one then it gave me a file not found error.
The opensource files were not in actual files so I feel like I should show you all my files and I feel weird uploading someone else's source to a github repo, so here is a rapid share link to the source files:
http://d01.megashares.com/dl/2YylIbE/SourceCodeAnd.offFile.zip
I feel weird sharing files like this^^ but I don't really see any other option. It just contains my .off file and .xml file and the C and C++ files.
Any help would be greatly appreciated, I've spent the past few days stuck on this.
Thanks!
Edit
So I ran it with g++ and with no parameters and these were the results:
$ g++ OFF-OpenGL_loader.cc
/tmp/ccNFneYn.o:OFF-OpenGL_loader.cc:(.text+0x1aa): undefined reference to
`ReadFile::getExtension(char*)'/tmp/ccNFneYn.o:
OFF-OpenGL_loader.cc:(.text+0x2f8): undefined reference to
operator>>(std::basic_ifstream<char, std::
char_traits<char> >&, ReadFile&)'/tmp/ccNFneYn.o:OFF-
OpenGL_loader.cc:(.text+0x6de): undefined reference to `ReadFile::ReadFile()'/tmp/ccNFneYn.o:OFF-
OpenGL_loader.cc:(.text+0x6f9): undefined reference to `ReadFile::~ReadFile()'/usr/lib/gcc/i686-pc-
cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld:
/tmp/ccNFneYn.o: bad reloc address 0x1c in section
`.gcc_except_table'/usr/lib/gcc/i686-pc-cygwin/3.4.4/.
./../../../i686-pc-cygwin/bin/ld: final link failed:
Invalid operationcollect2: ld returned 1 exit status
What kind of errors am I looking for?
The problem was that when I ran my program in Visual Studio it would both compile and run the program, and because the source required parameters to be run, it would come up with runtime errors.
Then because I didn't know how to pass parameters to programs in visual studio, I tried using Cygwin which gave me errors, probably because it wasn't configured correctly. Not really sure why those errors happened.
So to solve this whole thing I just built my program with Visual Studio, navigated to the .exe file that it creates when it compiles, and then ran that .exe in the command line.
So the moral of the story is: always remember that when you hit that green play button, it both compiles and runs the program. So if your error has to do with the circumstances that you run your program in, you might get errors even if your code is perfectly fine.
Thanks Bo Persson for helping me get that idea!