I'm attempting to run a SQL script from within Apache Ant using the execute tag for sqlplus.
<exec dir="src/sql" executable="sqlplus" failonerror="true" output="src/sql/test.sql.err">
<arg value="${db.login}"/>
<arg value="#test.sql"/>
</exec>
Sqlplus is working from the command line using the same arguments.
Ant, however returns:
dyld: Library not loaded: /ade/b/2649109290/oracle/sqlplus/lib/libsqlplus.dylib
For the command line I have set:
export DYLD_LIBRARY_PATH=/Applications/instantclient_11_2/
Is there an equivalent action I need to take for Ant to find the libraries?
One option is to give SQLcl a try.
It's the sql scripting engine from sqldev which is sqlplus , plus a lot more
http://www.oracle.com/technetwork/developer-tools/sqlcl/overview/sqlcl-index-2994757.html
The benefit is there there's no libraries it's self contained and uses the JDBC Thin driver for db connectivity.
Here's your ANT example..
<project name="sqlcl" basedir=".">
<property name="db.login" value="klrice/klrice"/>
<target name="sqlcl">
<exec dir="." executable="/Users/klrice/Downloads/sqlcl/bin/sql"
failonerror="true"
output="sql/test.sql.err">
<arg value="${db.login}"/>
<arg value="#sql/dual.sql"/>
</exec>
</target>
</project>
Then running...
$ ant sqlcl
Buildfile: /Users/klrice/build.xml
sqlcl:
BUILD SUCCESSFUL
Total time: 3 seconds
587211042:~ klrice$ more sql/test.sql.err
SQLcl: Release 17.4.0 Production on Wed Mar 07 21:59:54 2018
Copyright (c) 1982, 2018, Oracle. All rights reserved.
Last Successful login time: Wed Mar 07 2018 22:00:08 -05:00
Connected to:
Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production
login.sql found in the CWD. DB access is restricted for login.sql.
Adjust the SQLPATH to include the path to enable full functionality.
1
----------
1
Disconnected from Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production
Using the solution #kris-rice suggested, here is my implementation including checking for errors...
<!-- =================================================================== -->
<!-- load plsql tox -->
<!-- =================================================================== -->
<target name="compile.plsql.tox" description="compile plsql for tox">
<echo message="compile.plsql.tox --------------------"/>
<mkdir dir="tmp/log"/>
<exec dir="src/sql" executable="sql" failonerror="true" output="src/sql/tox.all.sql.err">
<arg value="${db.login.tox}"/>
<arg value="#tox.all.sql"/>
</exec>
<echo message="looking for plsql errors -------------------"/>
<exec dir="src/sql" executable="grep" failonerror="false" resultproperty="found">
<arg value="LINE/COL ERROR"/>
<arg value="tox.all.sql.err"/>
</exec>
<fail message="plsql compile errors">
<condition>
<equals arg1="${found}" arg2="0"/>
</condition>
</fail>
<echo message="looking for line item errors ---------------"/>
<exec dir="src/sql" executable="grep" failonerror="false" resultproperty="found">
<arg value="ERROR at"/>
<arg value="tox.all.sql.err"/>
</exec>
<fail message="sql compile errors">
<condition>
<equals arg1="${found}" arg2="0"/>
</condition>
</fail>
<echo message="compile.plsql.tox --------------------"/>
</target>
<!-- =================================================================== -->
Related
I have some code:
<exec executable="src/main/webapp/bin/webdriver.bat" failonerror="true" resultproperty="return.code">
<arg line="${ccc}/eeee--report-format JSON --report-file testResultserer/resultere-data/wwwww.json"/>
</exec> (1)
So, now I would like to exec command , when (1) are going fail.
How can I do this.
You can set property with the value of the return code and then execute the other command conditionally on the property's value:
<project>
<exec executable="${cmd}" resultproperty="ret1"/>
<condition property="cmd1failed" value="true">
<not>
<equals arg1="0" arg2="${ret1}"/>
</not>
</condition>
<exec executable="echo" xmlns:if="ant:if" if:true="${cmd1failed}">
<arg value="${cmd} failed"/>
</exec>
<exec executable="echo" xmlns:unless="ant:unless" unless:true="${cmd1failed}">
<arg value="${cmd} didn't fail"/>
</exec>
</project>
For example
$ ant -f exec.xml -Dcmd=/bin/true
Buildfile: /tmp/exec.xml
[exec] /bin/true didn't fail
BUILD SUCCESSFUL
Total time: 0 seconds
$ ant -f exec.xml -Dcmd=/bin/false
Buildfile: /tmp/exec.xml
[exec] Result: 1
[exec] /bin/false failed
BUILD SUCCESSFUL
Total time: 0 seconds
This uses the if/unless attributes introduced with Ant 1.9.1.
If you are using an older version of Ant, you'll have to use separate targets, something like
<project default="both">
<target name="cmd1">
<exec executable="${cmd}" resultproperty="ret1"/>
<condition property="cmd1failed" value="true">
<not>
<equals arg1="0" arg2="${ret1}"/>
</not>
</condition>
</target>
<target name="cmd1-fail" depends="cmd1" if="cmd1failed">
<exec executable="echo">
<arg value="${cmd} failed"/>
</exec>
</target>
<target name="cmd1-pass" depends="cmd1" unless="cmd1failed">
<exec executable="echo">
<arg value="${cmd} didn't fail"/>
</exec>
</target>
<target name="both" depends="cmd1-fail,cmd1-pass"/>
</project>
When I try to set some varible with ant's exec task, it doesn't seem to set to my required value. Not sure what's wrong here.
It works perfectly file when I set & echo from command line with cmd.
<exec executable="cmd">
<arg value="set"/>
<arg value="MY_VAR=SOME_VAL"/>
</exec>
-->
<echo message="MY_VAR is set to %MY_VAR%"/>
And output looks like:
exec
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\MY_PROJ_BASE_DIR_HERE>
echo
MY_VAR is set to **%MY_VAR%**
Use the /C option of cmd.exe.
build.xml
<project name="ant-exec-cmd-with-env-key" default="run">
<target name="run">
<exec executable="cmd" failonerror="true">
<env key="MY_VAR" value="SOME_VAL"/>
<arg value="/c"/>
<arg value="echo %MY_VAR%"/>
</exec>
</target>
</project>
Output
run:
[exec] SOME_VAL
Are you sure the problem is not in your reading of the variable?
<property environment="env"/>
<property name="MY_VAR" value="${env.MY_VAR}"/>
I have a script which detects OS using Catalina.bat for windows and Catalina.sh for UNIX..it executes successfully for UNIX but for windows its not able to extract OS version from Catalina.bat..the reason i find out is because in Catalina.bat when it executes this line
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome
then OS version statement is not reached in catalina.bat file,so the solution to this is i guess; explicitly set CATALINA_HOME environment variable using my Ant script itself; how to do that plz suggest any solution.
i was using this code, here OS.version property should have cached the OS version from catalina.bat file similar code in UNIX is working fine but win i wonder whats wrong
<property name="version" location="${My_proj}\tomcat\bin\catalina.bat"/>
<exec executable="${version}" outputproperty="OS.version">
<arg value="version" />
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="OS Name:"/>
<replacestring from="OS Name: " to=""/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
PROBLEM O SOLVED: you were right ..
<exec executable="cmd" outputproperty="tomcat.version">
<arg value="/c"/>
<arg value="${MY_PROJ}\tomcat\bin\version.bat"/>
<env key="CATALINA_HOME" value="${MY_PROJ}\tomcat\"/>
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="Server version"/>
<replaceregex pattern="Server version: Apache Tomcat/(.*)$" replace="\1"/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
<echo message="tomcat.version: ${tomcat.version}"/>
OUTPUT:
versioncat:
[echo] tomcat.version: 6.0.33
LAST BUL NOT THE LEAST CAN ANY1 ANSWER OR SUGGEST A WORKAROUND FOR MY LAST COMMENT QUERY THE SILLY QUESTION
If I understand correctly, you are executing this OS detection from Ant. In that case, can you not instead use Ant's built-in support for OS identification - in the os condition?
However, if you really need to execute catalina.bat while setting CATALINA_HOME, you could do so using a nested env element in you exec task.
Here is a sample build file which uses both approaches:
<project default="test">
<target name="test">
<!-- Execute a command, in this case a simple bat file
which echoes the value of the var set in the env block
-->
<exec executable="cmd">
<arg value="/c"/>
<arg value="test.bat"/>
<env key="CATALINA_HOME" value="whatever"/>
</exec>
<!-- echo the values of built-in OS related properties -->
<echo message="os.arch: ${os.arch}"/>
<echo message="os.name: ${os.name}"/>
<echo message="os.version: ${os.version}"/>
<!-- test one of the os conditions -->
<condition property="is.windows">
<os family="windows"/>
</condition>
<echo message="is.windows ? ${is.windows}"/>
</target>
</project>
Here is the content of test.bat:
echo CATALINA_HOME=%CATALINA_HOME%
Here is the output:
test:
[exec]
[exec] C:\tmp\ant>echo CATALINA_HOME=whatever
[exec] CATALINA_HOME=whatever
[echo] os.arch: x86
[echo] os.name: Windows XP
[echo] os.version: 6.1 build 7601 Service Pack 1
[echo] is.windows ? true
Regarding your subsequent question (in comments) about tomcat version...
I now guess you are executing this version detection via Ant in your runtime environment.
Ant and Java don't know about your Tomcat environment, so now you're back to executing %CATALINA_HOME%\bin\catalina.bat -version and parsing what you need from the output.
Here's a working example:
<project default="version">
<property environment="env"/>
<condition property="script.ext" value="bat">
<os family="windows"/>
</condition>
<condition property="script.ext" value="sh">
<os family="unix"/>
</condition>
<target name="version">
<exec executable="${env.CATALINA_HOME}/bin/version.${script.ext}" outputproperty="tomcat.version">
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="Server version"/>
<replaceregex pattern="Server version: Apache Tomcat/(.*)$" replace="\1"/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
<echo message="tomcat.version: ${tomcat.version}"/>
</target>
</project>
And here is the output:
version:
[echo] tomcat.version: 5.5.33
Note that this example assumes that you have the CATALINA_HOME (and JAVA_HOME) environment variable set in your terminal.
Alternatively, you could pass these variables using a nested <env> element as previously discussed. But it seems more likely that these should come from the runtime environment rather than embedded in your build file.
Do it like this :
<condition property="catalina.path" value="C:\Foo\catalina.bat">
<os family="windows"/>
</condition>
<condition property="catalina.path" value="/home/foo/catalina.sh">
<os family="unix"/>
</condition>
<exec> ... execute your script here </exec>
Depending on your situation, you may find this approach a little more platform agnostic and less error prone as you do not need to fork off a shell. This works at least as far back as Tomcat 6.x
<property environment="env"/>
<loadproperties>
<zipentry zipfile="${env.CATALINA_HOME}/bin/bootstrap.jar" name="META-INF/MANIFEST.MF"/>
<filterchain>
<prefixlines prefix="tomcat."/>
</filterchain>
</loadproperties>
<!-- Prints MAJOR.MINOR version, e.g.: 8.0 -->
<echo message="Tomcat Version: ${tomcat.Specification-Version}"/>
<!-- Prints full version, e.g.: 8.0.26 -->
<echo message="Tomcat Release: ${tomcat.Implementation-Version}"/>
I have gone through number of posts on the very forum but couldn't sort it out. I am trying to run a BAT file from ANT script. The folder hierarchy is like this
- Project
| - build.xml
| - build-C
| | - test.bat
The ANT file that i wrote so for is
<project name="MyProject" basedir=".">
<property name="buildC" value="${basedire}\build-C" />
<exec dir="${buildC}" executable="cmd" os="Windows XP">
<arg line="/c test.bat"/>
</exec>
</project>
The bat file content is
echo In Build-C Test.bat
It says that build failed .. :s i dun know what wrong am i doing ?
<property name="buildC" value="${basedire}\build-C" />
This should be ${basedir} I guess? Use
<echo>${buildC}</echo>
to make sure the dir is correct.
And shouldn't
<exec dir="${buildC}" executable="test.bat" os="Windows XP" />
do the job?
Hopefully this will help expand on the already given/accepted answers:
I suggest executing cmd with the batch script as a parameter:
<exec failonerror="true" executable="cmd" dir="${buildC}">
<arg line="/c "${buildC}/test.bat""/>
</exec>
Not sure if it is necessary to use the absolute path "${buildC}/test.bat" since dir is specified, but I put it just in case. It might be enough to use /c test.bat.
My project executes a batch script on Windows operating systems & a shell script on all others. Here is an example:
<target name="foo">
<!-- properties for Windows OSes -->
<condition property="script.exec" value="cmd">
<os family="windows"/>
</condition>
<condition property="script.param" value="/c "${basedir}/foo.bat"">
<os family="windows"/>
</condition>
<!-- properties for non-Windows OSes -->
<property name="script.exec" value="sh"/>
<property name="script.param" value=""${basedir}/foo.sh""/>
<echo message="Executing command: ${script.exec} ${script.param}"/>
<exec failonerror="true" executable="${script.exec}" dir="${basedir}">
<arg line="${script.param}"/>
</exec>
</target>
I have a target which will run a executable and get a version. But I need to remove stuff till the delimeter. Help me please.
<target name="tomcatVersion">
<exec executable="${WT_HOME}/tomcat/bin/catalina.bat" outputproperty="tomcat.version">
<arg value="version" />
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="Server number:"/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
<echo message="${tomcat.version}"/>
</target>
[Update: single step loadresource method with thanks to Matt]
You could do this by reading the output of the executable into a property and then filtering the property through a replaceregexp token filter to extract the string you require. For example:
<project default="get-version">
<target name="get-version">
<exec executable="bash" outputproperty="version.output">
<arg value="ant"/>
<arg value="-version"/>
</exec>
<loadresource property="version">
<string value="${version.output}"/>
<filterchain>
<tokenfilter>
<replaceregex pattern="[^\d]*(\d.\d.\d).*" replace="\1"/>
</tokenfilter>
<striplinebreaks/>
</filterchain>
</loadresource>
<echo level="info" message="version is: '${version}'"/>
</target>
</project>
Sample output:
$ ant -version
Apache Ant(TM) version 1.8.2 compiled on December 20 2010
$ ant
Buildfile: build.xml
get-version:
[echo] version is: '1.8.2'
BUILD SUCCESSFUL
Total time: 2 seconds
(I am using ant -version as a handy stand in for whatever executable you are running. I am aware that Ant version can be got from Ant properties.)
With older versions of Ant (<1.7) you could do this in two steps:
Write the output of the executable to file
Read the file through a replaceregexp token filter
For example:
<project default="get-version">
<target name="get-version">
<exec executable="bash" output="version.out">
<arg value="ant"/>
<arg value="-version"/>
</exec>
<loadfile property="version" srcfile="version.out">
<filterchain>
<tokenfilter>
<replaceregex pattern="[^\d]*(\d.\d.\d).*" replace="\1"/>
</tokenfilter>
<striplinebreaks/>
</filterchain>
</loadfile>
<echo level="info" message="version is: '${version}'"/>
</target>
</project>
Sample output
$ ant -version
Apache Ant version 1.6.5 compiled on June 2 2005
$ ant
Buildfile: build.xml
get-version:
[echo] version is: '1.6.5'
BUILD SUCCESSFUL
Total time: 2 seconds
The exec task has 3 attributes to catch the output from an executable :
outputproperty => catches stdout
errorproperty => catches stderr
resultproperty => catches returncode
see Ant Manual for exec task
So for your purpose :
use outputproperty to catch the
version written to stdout
grep the versionstring from
outputproperty via String replace
function from Ant Plugin Flaka
<project xmlns:fl="antlib:it.haefelinger.flaka">
<exec executable="bash" outputproperty="bashversion">
<arg value="--version"/>
</exec>
<fl:let>bashversion ::= '#{replace('${bashversion}','$2','(?s)(.+)(\d\.\d\.\d\(.\)?)(.+)')}'</fl:let>
<fl:echo>
Bashversion => ${bashversion}
</fl:echo>
</project>
output :
[fl:echo] Bashversion => 4.1.7(1)