Javac bootclasspath option - javac

I try to add -bootclasspath option when compiling java source like this:
javac -classpath lib/* -target 1.6 -source 1.6 -bootclasspath /usr/lib/jvm/java-7-oracle/lib/*.jar Hello.java
I am getting the following error when compiling:
javac: invalid flag: /usr/lib/jvm/java-7-oracle/lib/dt.jar
Usage: javac <options> <source files>
use -help for a list of possible options
How should I add the bootclasspath parameter?

The shell expands /usr/lib/jvm/java-7-oracle/lib/*.jar to the list of jars, so effectively javac is called like that:
javac ... -bootclasspath /usr/lib/jvm/java-7-oracle/lib/rt.jar /usr/lib/jvm/java-7-oracle/lib/dt.jar ... Hello.java
You can avoid that by putting the path between single quotes:
javac ... -bootclasspath '/usr/lib/jvm/java-7-oracle/lib/*.jar' ... Hello.java

I added this -bootclasspath /usr/lib/jvm/java-7-oracle/jre/lib/rt.jar instad of /usr/lib/jvm/java-7-oracle/lib/*.jar and it worked fine.

Try something like this:
java -bootclasspath $(set -- /usr/lib/jvm/java-7-oracle/lib/*.jar ; IFS=:; echo "$*")
Be running bash when you try it, the bourne again shell is the bee's knees.

Related

xonsh "which" equivalent - how to test if a (subprocess mode) command is available?

I would like to test (from xonsh) if a command is available or not. If I try this from the xonsh command prompt:
which bash
Then it works:
user#server ~ $ which bash
/usr/bin/bash
But it does not work from xonsh script:
#!/usr/bin/env xonsh
$RAISE_SUBPROC_ERROR = True
try:
which bash
print("bash is available")
except:
print("bash is not available")
Because it results in this error:
NameError: name 'which' is not defined
I understand that which is a shell builtin. E.g. it is not an executable file. But it is available at the xnosh command prompt. Then why it is not available inside an xonsh script? The ultimate question is this: how can I test (from an xonsh script) if a (subprocess mode) command is available or not?
import shutil
print(shutil.which('bash'))
While nagylzs' answer led me to the right solution, I found it inadequate.
shutil.which defaults to os.environ['PATH']. On my machine, the default os.environ['PATH'] doesn't contain the active PATH recognized by xonsh.
~ $ os.environ['PATH']
'/usr/bin:/bin:/usr/sbin:/sbin'
I found I needed to pass $PATH to reliably resolve 'which' in the xonsh environment.
~ $ $PATH[:2]
['/opt/google-cloud-sdk/bin', '/Users/jaraco/.local/bin']
~ $ import shutil
~ $ shutil.which('brew', path=os.pathsep.join($PATH))
'/opt/homebrew/bin/brew'
The latest version of xonsh includes a built-in which command. Unfortunately, the version included will emit an error on stdout if the target isn't found, a behavior that is not great for non-interactive use.
As mentioned in another answer, which exists in the current version of xonsh (0.13.4 as of 15/12/2022) so your script would work. However, it outputs its own error message so it's necessary to redirect stderr to get rid of it.
Also, unless you redirect its stdout as well (using all>), it migh be a good idea to capture its output so the final version would look like this:
#!/usr/bin/env xonsh
$RAISE_SUBPROC_ERROR = True
try:
bash = $(which bash err> /dev/null)
print(f"bash is available: {bash}")
except:
print("bash is not available")

Using Xbuild with Xamarin.Android (formerly Mono for Android)

We have a Xamarin.Android project that we are trying to build using Jenkins on a Mac. The Solution file contains several different projects, one of which is the MonoDroid project. The MonoDroid Project is dependent upon the other projects in the solution.
The problem that I have is that when I use xbuild to build the solution file, I have no way to use the /t:PackageForAndroid target, since it only is valid for the MD Project File.
Currently in Jenkins, I'm doing it like this:
xbuild MyCoolDroidAp/MyCoolDroidApp.sln /p:Configuration=Release /t:Clean
xbuild MyCoolDroidApp/MyCoolDroidApp.sln /p:Configuration=Release /t:Build
xbuild MyCoolDroidApp/MyCoolDroidProject.csproj /p:Configuration=Release /t:PackageForAndroid
This is working, but it seems to me that there should be a way to eliminate the 3rd step. Does anyone have any insight?
You don't need to use Xamarin.Studio/MonoDevelop to sign & zipalign your APK, you can do that at the command line. I've had luck using rake to compile, sign, and zipalign my APK files. Would something like that work for you?
Failing that, here is a simple Powershell script that you could probably port over real easy:
# First clean the Release target.
msbuild.exe HelloWorld.csproj /p:Configuration=Release /t:Clean
# Now build the project, using the Release target.
msbuild.exe HelloWorld.csproj /p:Configuration=Release /t:PackageForAndroid
# At this point there is only the unsigned APK - sign it.
# The script will pause here as jarsigner prompts for the password.
# It is possible to provide they keystore password for jarsigner.exe by adding an extra command line parameter -storepass, for example
# -storepass <MY_SECRET_PASSWORD>
# If this script is to be checked in to source code control then it is not recommended to include the password as part of this script.
& 'C:\Program Files\Java\jdk1.6.0_24\bin\jarsigner.exe' -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore ./xample.keystore -signedjar
./bin/Release/mono.samples.helloworld-signed.apk
./bin/Release/mono.samples.helloworld.apk publishingdoc
# Now zipalign it. The -v parameter tells zipalign to verify the APK afterwards.
& 'C:\Program Files\Android\android-sdk\tools\zipalign.exe' -f -v 4
./bin/Release/mono.samples.helloworld-signed.apk ./helloworld.apk
Hope this helps.
The consensus around the interwebs seems to be that I am doing this the right way.
Regarding Signing your apk i'm using something like this as a part of my makefile and it works ok:
...
BUILD_DIR = ./builds/$(platform)
KEYSTORE_PATH = your_keystore_pass
STORE_PASS = your_keystore_pass
ANDROID_SDK_PATH = path/to/your/android/sdk/dir
#example ANDROID_SDK_PATH = /Developer/AndroidSDK
RES_APK = my_apk.apk
APK_NAME = my_signed_apk.apk
...
sign:
(cd $(BUILD_DIR); jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore $(KEYSTORE_PATH) -storepass $(STORE_PASS) result.apk $(STORE_PASS))
(cd $(BUILD_DIR); $(ANDROID_SDK_PATH)/tools/zipalign -v 4 result.apk $(APK_NAME))
(cd $(BUILD_DIR);rm result.apk)
(cd $(BUILD_DIR);rm $(RES_APK))
Hope this helps

Start erlang with user defined variable (using rebar)?

I'd like to be able to use the following macro in my modules:
-ifdef(debug).
My startup script looks something like the following:
#!/bin/sh
PWD="$(pwd)"
#NAME="$(basename $PWD)"
erl -pa "$PWD/ebin" deps/*/ebin -boot start_sasl \
-name foo#127.0.0.1 \
-debug 1 \
-s $NAME \
+K true \
+P 65536
What else would need to be added so that debug is defined in my module? I need this to be dynamic so I don't have to modify source code for deployment into production. Using different startup scripts per dev/qa/prod environments is fine, but modifying source code shouldn't be necessary.
With erlc this can be done with -Ddebug. I use rebar however, and am not sure how to do it with that. I've tried adding the following to my rebar.config:
{erl_opts, [{D, "debug"}]}.
This gives the following error:
{error,
{1,
erl_parse,
"bad term"}}
The define for the compiler in rebar.config should look like this:
{erl_opts, [{d, debug}]}.
Note: the syntax is exactly the same as the compiler module's syntax: http://www.erlang.org/doc/man/compile.html
Current version of rebar (rebar version: 2 date: 20111205_155958 vcs: git 54259c5) does support compiler defines, as well.
rebar -D <defines> compile
See rebar --help for more rebar options.
ifdef is a preprocessor macro, it gets evaluated and removed at compile time -- you would have to re-compile your module with something like erlc -Ddebug module.erl to change it. add the "-P" flag if you want to see the output from the preprocessor in module.P.
to get access to the "-debug 1" argument at runtime, you can use init:get_argument(debug).
# erl -debug 1
...
1> init:get_argument(debug).
{ok,[["1"]]}
2> init:get_argument(foo).
error

Compiling java programs from CLI using javac

I have the following directory structure form where I am invoking javac
src/ lib/ build/
Under src:
src/com/xyz/App.java -- contains the main class
src/com/xyz/base/j1.java
src/com/xyz/base/j2.java
src/com/xyz/exceptions/e1.java
src/com/xyz/hibernate/factory/hbf1.java
src/com/xyz/hibernate/helper/hbh1.java
Under lib:
lib/hibernate.jar
lib/commons.jar
At the top level, I am using the following javac command:
javac -verbose -classpath lib/hibernate.jar:lib/commons.jar -d ./build -sourcepath ./src com/xyz/*.java
and I receive the following output
javac: No match
How should the args be passed to javac?
And here is the ANSWER:
javac -verbose -d build -classpath lib/commons.jar:lib/hibernate.jar [complete path for ALL the directories]/*.java
javac won't expand wildcards, that's what your shell does. so when you specify com/xyz/*.java , that will not expand to anything, as those files are under src/ but the shell doesn't know that. If you list out every java file as com/xyz/Foo.java com/xyz/Bar.java etc, it should work.
(note that if you're on windows you'll need ; and not : to seperate classpaths)
Something like this might work:
javac -verbose -classpath build:lib/hibernate.jar:lib/commons.jar -d ./build ./src/com/xyz/base/*java ./src/com/xyz/exceptions/*.java ./src/com/xyz/hibernate/factory/*.java ./src/com/xyz/*.java
I'd not do this other than as an exercise on how to compile from a command line, otherwise use a build tool like ant

how to use execute() in groovy to run any command

I usually build my project using these two commands from command line (dos)
G:\> cd c:
C:\> cd c:\my\directory\where\ant\exists
C:\my\directory\where\ant\exists> ant -Mysystem
...
.....
build successful
What If I want to do the above from groovy instead? groovy has execute() method but following does not work for me:
def cd_command = "cd c:"
def proc = cd_command.execute()
proc.waitFor()
it gives error:
Caught: java.io.IOException: Cannot run program "cd": CreateProcess error=2, The
system cannot find the file specified
at ant_groovy.run(ant_groovy.groovy:2)
Or more explicitly, I think binil's solution should read
"your command".execute(null, new File("/the/dir/which/you/want/to/run/it/from"))
According to this thread (the 2nd part), "cd c:".execute() tries to run a program called cd which is not a program but a built-in shell command.
The workaround would be to change directory as below (not tested):
System.setProperty("user.dir", "c:")
"your command".execute(null, /the/dir/which/you/want/to/run/it/from)
should do what you wanted.
Thanks Noel and Binil, I had a similar problem with a build Maven.
projects = ["alpha", "beta", "gamma"]
projects.each{ project ->
println "*********************************************"
println "now compiling project " + project
println "cmd /c mvn compile".execute(null, new File(project)).text
}
I got to fix the issue by running a command as below:
i wanted to run git commands from git folder, so below is the code which worked for me.
println(["git","add","."].execute(null, new File("/Users/xyz/test-org/groovy-scripts/$GIT_REPOS/")).text)
println(["git","commit","-m","updated values.yaml"].execute(null, new File("/Users/xyz/test-org/groovy-scripts/$GIT_REPOS/")).text)
println(["git","push","--set-upstream","origin","master"].execute(null, new File("/Users/xyz/test-org/groovy-scripts/$GIT_REPOS/")).text)

Resources