While using java "setOptions" function with the bellow properties I am getting an error : "Quote parse error."...
"weka.classifiers.meta.OneClassClassifier -num \"weka.classifiers.meta.generators.GaussianGenerator -S 1 -M 0.0 -SD 1.0\" -nom \"weka.classifiers.meta.generators.NominalGenerator -S 1\" -trr 0.1 -tcl F&B -cvr 10 -cvf 10.0 -P 0.5 -S 1 -W weka.classifiers.meta.Bagging -- -P 100 -S 1 -num-slots 1 -I 10 -W weka.classifiers.trees.REPTree -- -M 2 -V 0.001 -N 3 -S 1 -L -1 -I 0.0"
I understand that this is occurring because of error in applying quotes, but I am not sure as to where they should be applied.
I thought of applying them before calling REPTree but that doesn't seem to work.
Whenever using a Weka classifier with Java code, use the weka.core.Utils.splitOptions method to parse the config string without worrying about quoting and escaping characters.
// set your configurations parameters here, e.g., "-S 1"
String options = "whatever configuration you want";
// instantiate the classifier object
REPTree tree = new REPTree();
// parse and set the classifier's configuration
tree.setOptions(Utils.splitOptions(options));
Also, remember to provide your current code and to format your question.
Related
I'm using the MaxEntVariableSelection package and repeatedly getting the following error when trying to execute VariableSelection even after setting all the things as explained in MaxentVAriableSelection Vignette. Any help to skip this error is much appreciated.
These occurrence/background CSV files do not contain NAs or Numbering column before the "species" column and have SWD format. All the files, raster layers and maxent.jar set in the same working directory. Raster layers are separate and in .asc format.
MaxentVariableSelection::VariableSelection(maxent="C:/Users/Piyali/Desktop/msc_paper/R_SDM/maxent.jar",
outdir="C:/Users/Piyali/Desktop/msc_paper/R_SDM/outputtest2",
gridfolder="/Users/Piyali/Desktop/msc_paper/R_SDM/30sclippedascii",
occurrencelocations="C:/Users/Piyali/Desktop/msc_paper/R_SDM/xocc_all.csv",
backgroundlocations="C:/Users/Piyali/Desktop/msc_paper/R_SDM/xbg_all.csv",
additionalargs="nolinear noquadratic noproduct nothreshold noautofeature",
contributionthreshold=5,
correlationthreshold=0.9,
betamultiplier=seq(2,6,0.5))
Error in .local(.Object, ...) :
In addition: Warning messages:
1: In system(paste("java -jar", maxent, "-o", outdir, "-j", gridfolder, :
running command 'java -jar C:/Users/Piyali/Desktop/msc_paper/R_SDM/maxent.jar -o C:/Users/Piyali/Desktop/msc_paper/R_SDM/outputtest2 -j /Users/Piyali/Desktop/msc_paper/R_SDM/30sclippedascii/ -s C:/Users/Piyali/Desktop/msc_paper/R_SDM/outputtest2/xocc_all.csv_VariableSubset.csv -e C:/Users/Piyali/Desktop/msc_paper/R_SDM/outputtest2/xbg_all.csv_VariableSubset.csv plots=false writeplotdata=false visible=false autorun=true randomseed=true writebackgroundpredictions=false replicates=10 replicatetype=subsample randomtestpoints=50 redoifexists writemess=false writeclampgrid=false askoverwrite=false pictures=false outputgrids=false -b 2 nolinear noquadratic noproduct nothreshold noautofeature' had status 1
2: In system(paste("java -jar", maxent, "-o", outdir, "-j", gridfolder, :
running command 'java -jar C:/Users/Piyali/Desktop/msc_paper/R_SDM/maxent.jar -o C:/Users/Piyali/Desktop/msc_paper/R_SDM/outputtest2 -j /Users/Piyali/Desktop/msc_paper/R_SDM/30sclippedascii/ -s C:/Users/Piyali/Desktop/msc_paper/R_SDM/outputtest2/xocc_all.csv_VariableSubset.csv -e C:/Users/Piyali/Desktop/msc_paper/R_SDM/outputtest2/xbg_all.csv_VariableSubset.csv plots=false writeplotdata=false visible=false autorun=true randomseed=true writebackgroundpredictions=false redoifexists writemess=false writeclampgrid=false askoverwrite=false pictures=false outputformat=raw -b 2 nolinear noquadratic noproduct nothreshold noautofeature' had status 1
Error in .rasterObjectFromFile(x, band = band, objecttype = "RasterLayer", :
Cannot create a RasterLayer object from this file. (file does not exist)
If anyone finds this error in the future, check whether the column names of the variables in occurrence/background CSV files are exactly similar to the names of raster layers you have provided.
I am trying to format a variable in linux
str="Initial Value = 168"
echo "New Value=$(echo $str| cut -d '=' -f2);">>test.txt
I am expecting the following output
Value = 168;
But instead get
Value = 168 ^M;
Don't edit your bash script on DOS or Windows. You can run dos2unix on the bash script. The issue is that Windows uses "\r\n" as a line separator, Linux uses "\n". You can also manually remove the "\r" characters in an editor on Linux.
str="Initial Value = 168"
newstr="${str##* }"
echo "$newstr" # 168
pattern matching is the way to go.
Try this:
#! /bin/bash
str="Initial Value = 168"
awk '{print $2"="$4}' <<< $str > test.txt
Output:
cat test.txt
Value=168
I've got comment saying that it doesn't address ^M, I actually does:
echo -e 'Initial Value = 168 \r' | cat -A
Initial Value = 168 ^M$
After awk:
echo -e 'Initial Value = 168 \r' | awk '{print $2"="$4}' | cat -A
Value=168$
First off, always quote your variables.
#!/bin/bash
str="Initial Value = 168"
echo "New Value=$(echo "$str" | cut -d '=' -f2);"
For me, this results in the output:
New Value= 168;
If you're getting a carriage return between the digits and the semicolon, then something may be wrong with your echo, or perhaps your input data is not what you think it is. Perhaps you're editing your script on a Windows machine and copying it back, and your variable assignment is getting DOS-style newlines. From the information you've provided in your question, I can't tell.
At any rate I wouldn't do things this way. I'd use printf.
#!/bin/bash
str="Initial Value = 168"
value=${str##*=}
printf "New Value=%d;\n" "$value"
The output of printf is predictable, and it handily strips off gunk like whitespace when you don't want it.
Note the replacement of your cut. The functionality of bash built-ins is documented in the Bash man page under "Parameter Expansion", if you want to look it up. The replacement I've included here is not precisely the same functionality as what you've got in your question, but is functionally equivalent for the sample data you've provided.
I have the following difficult to read script consisting of a single command:
#!/bin/sh
/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
-classpath /Users/afarber/src/jetty-newbie/EmbeddedWebsocket/target/classes:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-server/9.3.9.v20160517/jetty-server-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-http/9.3.9.v20160517/jetty-http-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-servlet/9.3.9.v20160517/jetty-servlet-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-security/9.3.9.v20160517/jetty-security-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-server/9.3.9.v20160517/websocket-server-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-servlet/9.3.9.v20160517/websocket-servlet-9.3.9.v20160517.jar \
de.afarber.MyServlet
As slight readability improvement I would like to list all the paths after the -classpath in a separate variable, each aligned after the other:
PATHS= /Users/afarber/src/jetty-newbie/EmbeddedWebsocket/target/classes \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-server/9.3.9.v20160517/jetty-server-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-http/9.3.9.v20160517/jetty-http-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-servlet/9.3.9.v20160517/jetty-servlet-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-security/9.3.9.v20160517/jetty-security-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-server/9.3.9.v20160517/websocket-server-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-servlet/9.3.9.v20160517/websocket-servlet-9.3.9.v20160517.jar
This way I can easier add and remove the paths, and sort them in Vim.
My question is: how to join them back for my command?
UPDATE:
If all JAR-files would be located in the same dir, I could have used the new Java 8 wildcard syntax java -classpath "/that/dir/*" de.afarber.MyServlet - but that wasn't the case here.
I suggest using heredoc for easy maintenance of this long list of class paths:
#!/bin/bash
# populate array cpath with all the the classpaths each one on different lines
read -d '' -ra cpath<<'EOF'
/Users/afarber/src/jetty-newbie/EmbeddedWebsocket/target/classes
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-server/9.3.9.v20160517/jetty-server-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-http/9.3.9.v20160517/jetty-http-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-servlet/9.3.9.v20160517/jetty-servlet-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-security/9.3.9.v20160517/jetty-security-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-server/9.3.9.v20160517/websocket-server-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-servlet/9.3.9.v20160517/websocket-servlet-9.3.9.v20160517.jar
EOF
# merge them with : as separator in classpath
printf -v classpath "%s:" "${cpath[#]}"
# execute the java command line
/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
-classpath "${classpath%:}" de.afarber.MyServlet
Since you are using bash, you can store the directory names in an array (with some refactoring just to make this example more readable):
repo=/Users/afarber/.m2/repository
jetty="$repo/org/eclipse/jetty"
websocket="$jetty/websocket"
paths=(
/Users/afarber/src/jetty-newbie/EmbeddedWebsocket/target/classes
"$jetty"/jetty-server/9.3.9.v20160517/jetty-server-9.3.9.v20160517.jar
$repo/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar
"$jetty"/jetty-http/9.3.9.v20160517/jetty-http-9.3.9.v20160517.jar
"$jetty"/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar
"$jetty"/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar
"$jetty"/jetty-servlet/9.3.9.v20160517/jetty-servlet-9.3.9.v20160517.jar
"$jetty"/jetty-security/9.3.9.v20160517/jetty-security-9.3.9.v20160517.jar
"$websocket"/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar
"$websocket"/websocket-server/9.3.9.v20160517/websocket-server-9.3.9.v20160517.jar
"$websocket"/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar
"$websocket"/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar
"$websocket"/websocket-servlet/9.3.9.v20160517/websocket-servlet-9.3.9.v20160517.jar
)
Note you don't need to end each line with a backslash; whitespace (including newlines) separate elements of the array. Once you have the array, you can join the elements with a colon using parameter expansion with a modified value of the IFS parameter.
/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
-classpath "$(IFS=:; echo "${paths[*]}")" de.afarber.MyServlet
A sed should do the trick:
colonPATHS=$(echo "$PATHS" | sed -r 's/\s+/:/g')
echo "$colonPATHS"
The sed turns sequences of whitespace into a ":".
Simple sed can do this
pathwithcolons=`echo $PATHS|sed 's/ \+\\ \+/:/g'`
I've ended up using the following script:
#!/bin/sh
REPO=/Users/afarber/.m2/repository
VERSION=9.3.9.v20160517
CPATHS=/Users/afarber/src/jetty-newbie/WebsocketServlet/target/classes
CPATHS=$CPATHS:$REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-http/$VERSION/jetty-http-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-io/$VERSION/jetty-io-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-security/$VERSION/jetty-security-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-server/$VERSION/jetty-server-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-servlet/$VERSION/jetty-servlet-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-util/$VERSION/jetty-util-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-api/$VERSION/websocket-api-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-client/$VERSION/websocket-client-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-common/$VERSION/websocket-common-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-server/$VERSION/websocket-server-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-servlet/$VERSION/websocket-servlet-$VERSION.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
-classpath $CPATHS de.afarber.MyServlet
I like it better than other solutions, because it does not spawn additional processes (like sed), is easier to read and can be translated to Windows CMD batch file:
#echo off
set REPO="C:\Users\user1\.m2\repository"
set VERSION=9.3.9.v20160517
set CPATHS=C:\Users\user1\jetty-newbie\WebsocketServlet\target\classes
set CPATHS=%CPATHS%;%REPO%\javax\servlet\javax.servlet-api\3.1.0\javax.servlet-api-3.1.0.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-http\%VERSION%\jetty-http-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-io\%VERSION%\jetty-io-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-security\%VERSION%\jetty-security-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-server\%VERSION%\jetty-server-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-servlet\%VERSION%\jetty-servlet-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-util-ajax\%VERSION%\jetty-util-ajax-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-util\%VERSION%\jetty-util-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-api\%VERSION%\websocket-api-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-client\%VERSION%\websocket-client-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-common\%VERSION%\websocket-common-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-server\%VERSION%\websocket-server-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-servlet\%VERSION%\websocket-servlet-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\postgresql\postgresql\9.4.1208.jre7\postgresql-9.4.1208.jre7.jar
"C:\Program Files\Java\jdk1.8.0_66\bin\java.exe" -cp %CPATHS% de.afarber.MyServlet
In a web scanner application, i need to parse some script's output to get some informations, but the problem is that i don't get the same output in linux shell and in java output, let me describe it (this example is done with whatweb on one of the websites i need to scan at work, but i also have this problem whenever i have a colored output in shell):
Here is what i get from linux's output (with some colors):
http://www.ceris-ingenierie.com [200] Apache[2.2.9], Cookies[ca67a6ac78ebedd257fb0b4d64ce9388,jfcookie,jfcookie%5Blang%5D,lang], Country[EUROPEAN UNION][EU], HTTPServer[Fedora Linux][Apache/2.2.9 (Fedora)], IP[185.13.64.116], Joomla[1.5], Meta-Author[Administrator], MetaGenerator[Joomla! 1.5 - Open Source Content Management], PHP[5.2.6,], Plesk[Lin], Script[text/javascript], Title[Accueil ], X-Powered-By[PHP/5.2.6, PleskLin]
And here is what i get from Java:
[1m[34mhttp://www.ceris-ingenierie.com[0m [200] [1m[37mApache[0m[[1m[32m2.2.9[0m], [1m[37mCookies[0m[[1m[33mca67a6ac78ebedd257fb0b4d64ce9388,jfcookie,jfcookie%5Blang%5D,lang[0m], [1m[37mCountry[0m[[1m[33mEUROPEAN UNION[0m][[1m[35mEU[0m], [1m[37mHTTPServer[0m[[1m[31mFedora Linux[0m][[1m[36mApache/2.2.9 (Fedora)[0m], [1m[37mIP[0m[[1m[33m185.13.64.116[0m], [1m[37mJoomla[0m[[1m[32m1.5[0m], [1m[37mMeta-Author[0m[[1m[33mAdministrator[0m], [1m[37mMetaGenerator[0m[[1m[33mJoomla! 1.5 - Open Source Content Management[0m], [1m[37mPHP[0m[[1m[32m5.2.6,[0m], [1m[37mPlesk[0m[[1m[33mLin[0m], [1m[37mScript[0m[[1m[33mtext/javascript[0m], [1m[37mTitle[0m[[32mAccueil [0m], [1m[37mX-Powered-By[0m[[1m[33mPHP/5.2.6, PleskLin[0m]
My guess is that colors in linux's shell are generated by those unknown characters, but they are really a pain for parsing in java.
I get this output by running the script in a new thread, and doing raw_data+=data;(where raw_data is a String) whenever i have a new line in my output, to finally send raw_data to my parser.
How can i do to avoid getting those annoying chars and so, to get a more friendly output like i get in linux's shell?
In your Java code, where you are executing the shell script, you can add an extra sed filter to filter out the shell-control characters.
# filter out shell control characters
./my_script | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
Use tr -dc '[[:print:]]' to remove non-printable characters, like this:
# filter out shell control characters
./my_script | \
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | \
tr -dc '[[:print:]]'
You could even add a wrapper script around the original script to do this. And call the wrapper script. This allows you to do any other pre-processing, before feeding it into the Java program and keeps it clean of all unnecessary code and you can focus on the core logic of the application.
If you can't add a wrapper script for any reason and would like to add the filter in Java, Java doesn't support pipes in the command, directly. You'll have to call your command as an argument to bash it like this:
String[] cmd = {
"/bin/sh",
"-c",
"./my_script | sed -r 's/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g'"
};
Process p = Runtime.getRuntime().exec(cmd);
Don't forget to escape all the '\' when you use the regex in Java.
Source and description for the sed filter: http://www.commandlinefu.com/commands/view/3584/remove-color-codes-special-characters-with-sed
You can use a regex here:
String raw_data= ...;
String cleaned_raw_data = raw_data.replaceAll("\\[\\d+m", "");
This will remove any sequence of characters starting with a \\[, ending with a m and having between them one or more digit (\\d+).
Note that [ is preceded by a \\ because [ has a special meaning for regular expressions (it's a meta-character).
Description
I'm working on a configuration script for a JNI wrapper. One of the configuration parameters is the path to jni.h. What's a good quick-and-dirty Autoconf test for whether this parameter is set correctly for C++ compilation? You can assume you're running on Linux and g++ is available.
Alternatively, is there a way to get javah (or a supporting tool) to give me this path directly?
Then there is the easy way: http://www.gnu.org/software/autoconf-archive/ax_jni_include_dir.html
Sometimes it is best to just use the standard recipies.
Checking for headers is easy; just use AC_CHECK_HEADER. If it's in a weird place (i.e., one the compiler doesn't know about), it's entirely reasonable to expect users to set CPPFLAGS.
The hard part is actually locating libjvm. You typically don't want to link with this; but you may want to default to a location to dlopen it from if JAVA_HOME is not set at run time.
But I don't have a better solution than requiring that JAVA_HOME be set at configure time. There's just too much variation in how this stuff is deployed across various OSes (even just Linux distributions). This is what I do:
AC_CHECK_HEADER([jni.h], [have_jni=yes])
AC_ARG_VAR([JAVA_HOME], [Java Runtime Environment (JRE) location])
AC_ARG_ENABLE([java-feature],
[AC_HELP_STRING([--disable-java-feature],
[disable Java feature])])
case $target_cpu in
x86_64) JVM_ARCH=amd64 ;;
i?86) JVM_ARCH=i386 ;;
*) JVM_ARCH=$target_cpu ;;
esac
AC_SUBST([JVM_ARCH])
AS_IF([test X$enable_java_feature != Xno],
[AS_IF([test X$have_jni != Xyes],
[AC_MSG_FAILURE([The Java Native Interface is required for Java feature.])])
AS_IF([test -z "$JAVA_HOME"],
[AC_MSG_WARN([JAVA_HOME has not been set. JAVA_HOME must be set at run time to locate libjvm.])],
[save_LDFLAGS=$LDFLAGS
LDFLAGS="-L$JAVA_HOME/lib/$JVM_ARCH/client -L$JAVA_HOME/lib/$JVM_ARCH/server $LDFLAGS"
AC_CHECK_LIB([jvm], [JNI_CreateJavaVM], [LIBS=$LIBS],
[AC_MSG_WARN([no libjvm found at JAVA_HOME])])
LDFLAGS=$save_LDFLAGS
])])
FYI - the patch below against the latest ax_jni_include_dir.m4 works for me on Macos 11.1.
--- a/m4/ax_jni_include_dir.m4
+++ b/m4/ax_jni_include_dir.m4
## -73,13 +73,19 ## fi
case "$host_os" in
darwin*) # Apple Java headers are inside the Xcode bundle.
- macos_version=$(sw_vers -productVersion | sed -n -e 's/^#<:#0-9#:>#
*.\(#<:#0-9#:>#*\).#<:#0-9#:>#*/\1/p')
- if #<:# "$macos_version" -gt "7" #:>#; then
- _JTOPDIR="$(xcrun --show-sdk-path)/System/Library/Frameworks/JavaVM.framework"
- _JINC="$_JTOPDIR/Headers"
+ major_macos_version=$(sw_vers -productVersion | sed -n -e 's/^\(#<:#0-9#:>#*\).#<:#0-9#:>#*.#<:#0-9#:>#*/\1/p')
+ if #<:# "$major_macos_version" -gt "10" #:>#; then
+ _JTOPDIR="$(/usr/libexec/java_home)"
+ _JINC="$_JTOPDIR/include"
else
- _JTOPDIR="/System/Library/Frameworks/JavaVM.framework"
- _JINC="$_JTOPDIR/Headers"
+ macos_version=$(sw_vers -productVersion | sed -n -e 's/^#<:#0-9#:>#*.\(#<:#0-9#:>#*\).#<:#0-9#:>#*/\1/p')
+ if #<:# "$macos_version" -gt "7" #:>#; then
+ _JTOPDIR="$(xcrun --show-sdk-path)/System/Library/Frameworks/JavaVM.framework"
+ _JINC="$_JTOPDIR/Headers"
+ else
+ _JTOPDIR="/System/Library/Frameworks/JavaVM.framework"
+ _JINC="$_JTOPDIR/Headers"
+ fi
fi
;;
*) _JINC="$_JTOPDIR/include";;