You can always go via javap
. I know, I know. It's ugly, has lots of assumptions, but in case you desperately need to generate headers for lots of files it might be the only option.
#!/bin/bash
# FIRST_ARG - full class name (with package)
# SECOND_ARG - class path
CLASS_NAME=`javap -cp $2 $1 |
grep -v "Compiled from" |
grep "public class" |
cut -f3 -d" " |
awk -F"." '{ print $NF }'`
PACKAGE_NAME=`javap -cp $2 $1 |
grep -v "Compiled from" |
grep "public class" |
cut -f3 -d" " |
sed s/.${CLASS_NAME}$//`
DIR_NAME=`echo $PACKAGE_NAME | sed 's|.|/|g'`
mkdir -p java_jni/${DIR_NAME}
JAVA_FILE_NAME="java_jni/${DIR_NAME}/${CLASS_NAME}.java"
echo "package ${PACKAGE_NAME};" > ${JAVA_FILE_NAME}
echo "public class ${CLASS_NAME} {" >> ${JAVA_FILE_NAME}
javap -cp $2 $1 | grep "native" | while read line; do
param=0
comma=`echo $line | grep "," | wc -l`
while [ $comma -gt 0 ]; do
line=`echo $line | sed "s/,/ param_${param}|/"`
let param=param+1
comma=`echo $line | grep "," | wc -l`
done
line=`echo $line | sed "s/)/ param_${param})/" | sed 's/|/,/g'`
echo " $line" >> ${JAVA_FILE_NAME}
done
echo "}" >> ${JAVA_FILE_NAME}
mkdir -p c_header
javac -h c_header ${JAVA_FILE_NAME}
I bet it can be made way more beautiful.
For me, now, when I slowly start to think about inevitable move towards Java 10, and all these cases, where I might be surprised by non existing Java source code, I think it's not a bad idea to have some tool at my disposal. Just in case.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…