liquibase future rollback error with sqlFile tag: File not found - rollback

I've added the future-rollback tag to my ant script. What i want to do (and I think future-rollback is what Im looking for) is to generate an sql rollback script, but without executing it (rollback script must be delivered with sql scripts is the requirement from my client).
My changelog file has many changesets, some of which contain the <sqlFile> tag.
For example:
<databaseChangeLog ...>
<include file="latest/somesqlprocedure.xml" relativeToChangelogFile="true"/>
</databaseChangelog...>
Where the latest/somesqlprocedure.xml has an sqlFile tag.
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
<sqlFile path="${changelog.dir}/latest/myprocedure.sql" splitStatements="false" />
</changeSet>
</databaseChangeLog>
When I run the ant script, I get the following error
liquibase.exception.ChangeLogParseException:
Invalid Migration File: <sqlfile
path=${changelog.dir}/latest/myprocedure.sql>
- Could not find file
Does anyone has an idea of whats going on ?
This is a snippet of the build.xml file
<target name="db-future-rollback" depends="init">
<rollbackFutureDatabase
changeLogFile="${db.changelog.file}"
driver="${database.driver}"
url="${database.url}"
username="${database.username}"
password="${database.password}"
outputfile="${database.rollback.dir}"
promptOnNonLocalDatabase="${prompt.user.if.not.local.database}"
classpathref="project.classpath"
>
</rollbackFutureDatabase>
</target>
Thanks in advance.

The problem may be coming from using an absolute path in your sqlFile, rather than a classpath-relative path. The classpath relative path was what was originally supported in liquibase and is still better tested. The absolute path option was added recently, and the futureRollbackSql code may have not been patched to support it.
Can you try the sqlFile using a relative path?
As a side note, the relative path option is generally better because the filename is used in the databasechangelog table to note which changeSets have ran. If you use an absolute path, the entire path is stored and if you try to re-run the changelog from a different path (or running against the same database from a different machine), liquibase will think it is a different changeSet and try to re-run it.

Related

"Unexpected error running Liquibase: Unknown Reason" liquibase 3.3.5 and grails war file

This is the command I am running:
java -jar /root/liquibase/liquibase.jar \
--driver=com.mysql.jdbc.Driver \
--logLevel=debug \
--changeLogFile=migrations/changelog.xml \
--classpath=/usr/share/tomcat7/lib/mysql.jar:/var/lib/tomcat7/webapps/myApp.war \
--url="jdbc:mysql://127.0.0.1:3306/mydb" \
--username=myuser \
--password=mypass \
--contexts=MYCONTEXT \
update
this fails with the following unhelpful error message:
Unexpected error running Liquibase: Unknown Reason
SEVERE 9/9/15 2:23 PM: liquibase: Unknown Reason
java.lang.AbstractMethodError
at liquibase.database.DatabaseFactory.register(DatabaseFactory.java:87)
at liquibase.database.DatabaseFactory.<init>(DatabaseFactory.java:29)
at liquibase.database.DatabaseFactory.getInstance(DatabaseFactory.java:40)
at liquibase.integration.commandline.CommandLineUtils.createDatabaseObject(CommandLineUtils.java:50)
at liquibase.integration.commandline.Main.doMigration(Main.java:884)
at liquibase.integration.commandline.Main.run(Main.java:175)
at liquibase.integration.commandline.Main.main(Main.java:94)
I have no idea where to look. I have verified that the jars and wars are correct, i.e.
ls /root/liquibase/liquibase.jar
ls /usr/share/tomcat7/lib/mysql.jar
ls /var/lib/tomcat7/webapps/revolve.war
All list the corresponding file.
Any ideas?
the war exploded looks like this:
WEB-INF\classes\migrations\
changelog.xml
lots_of_other_changes.xml
WEB-INF\classes\migrations\sql
lots of sql files
I have tired lots of variations, including:
--changeLogFile=WEB-INF/classes/migrations/changelog.xml \
the changelogs work find if I run them on my local pc outside of a war file, although I do have to cd into the directory where the main changelog.xml file is first, otherwise it does not work.
The main changelog looks like this:
<databaseChangeLog
:
<include file="baseline.xml"/>
<include file="something.xml"/>
and these included files have things like this:
<changeSet id="something" author="me">
<comment>something</comment>
<sqlFile path="sql//something//new_things.sql" />
</changeSet>
NOTE:
using the grails in-application auto-updater feature with the data-migration 1.4.0 plug wont work, as it is hard coded to use liquibase version 2.0.5 which has major bugs.
using liquibase 3.4+ is not currently an option due to incompatibility.
If I try the command without including the war file location, I correctly get an error saying could not find the changelog file expected, and it creates the DATABASECHANGELOCK table in the db (so that side is ok)
No matter what I change changeLogFile ot, it always gives this error, even something completely wrong.
We dont want to go through the pain of generating diff sql, and running that sql.
I suspect the issue is to do with the relative paths of the includes in the change sets.
I also tried changing all the
<include file="something.xml"/>
to
<include file="something.xml" relativeToChangelogFile="true" />
and
<sqlFile path="sql//something//new_things.sql" />
to
<sqlFile relativeToChangelogFile="true" path="sql//something//new_things.sql" />
But this made no difference - same error. I tried exploding the war and running it on the exploded files - this works, but is not what we want (as there is no way to explode the war on the production machines - they dont have the jar command, and if we deploy the war to live servers, without the DB changes first, the live system will fail)
I don't know about Grails, but I'm immediately noticing those doubled-slashes in your paths. I would expect them to cause problems.
Are you perhaps thinking of the need to quote Windows-style backslashes? Where you see things like: C:\\path\\to\\file.dat.
But you don't need to do that for Unix-style slashes (or forward-slashes, if you will). (And if you did you'd still have to quote them with backslashes, like this: \/path\/to\/file.dat -- but don't do that.)
I have the same situation: using LiquiBase with a Grails application. I had to fall back to liquibase-core-2.0.5.jar, which is embedded in the Grails User Library. I could not figure out how to exclude the jar. Unfortunately, this version of LiquiBase is considered very buggy.

passing value to remote ant target

I have two ant files say antFile1.xml and antFile2.xml on windows and linux machine respectively.
antFile1.xml
<target name="executeOnLinux">
<sshexec
host="${remote.host.ip}"
username="${remote.user.id}"
password="${remote.user.ssh.password}"
command="ant -f antFile2.xml 'linuxAntTarget'"
trust="true"/>
</target>
antFile2.xml
<target name="linuxAntTarget">
<input message="Enter application edition number" addproperty="editionNo"/>
<echo message="${editionNo}"/>
</target>
When I execute the the target named "executeOnLinux" from antFile1.xml from my, it connects to the linux machine and starts executing the "linuxAntTarget" from antFile2.xml file. But, as soon as it reaches to the the point where user input is required keeps waiting since I am not able to pass the input. My question is how can I pass the value to it? Is this even possible or there is any other better way of doing it?
Since Ant 1.9.4, the sshexec task provides a useSystemIn attribute:
Whether to pass the current standard input to the remote process, defaults to false
You may also try the input attribute from the same task:
A file from which the executed command's standard input is taken. This attribute is mutually exclusive with the inputstring and inputproperty attributes.
When executing more than one command via commandResource, input will be read for each command. since Ant 1.8.0

What is this build.xml doing?

I am learning build.xml and am confused by the following code:
<macrodef name="a-test">
<attribute name="port" default="${PORT}"/> #1
<junit printsummary=...
<env key="PORT" value="#{port}" /> #2
...
when I run java with commandLine including -DPORT=8080 and then in java code I get port value 8080 by calling
String port = System.getenv(PORT).
What is the above build.xml doing? So far I know $ is to represent a property while # is to represent an attribute. Besides, the above code is the only place where PORT and port appear. What happens here so that port value are finally obtained in java code? Thanks.
The other question, what is the difference btw. using "env key" and using "sysproperty"? according to http://etutorials.org/Programming/Java+extreme+programming/Chapter+3.+Ant/3.6+Passing+Arguments+to+a+Buildfile/
sysproperty can be use to parse argument -D to java code, while env key is used to do the same thing right? Thanks.
Is there any detailed document about build.xml? the one I google from internet describer things so briefly.
What you see is macrodef in ant. There will be another place in build.xml(or other build.xml) where this is called by like
<a-test port=<value> ..

Openbravo ant build fails

I am trying to setup openbravo on eclipse environment with the above URL.
Development stack setup is done successfully. (ANT, Java, Postgresql)
At the openbravo source directory when i apply the command
ant install.source
Build failure due to errors -
/home/pos/sourcecode_openbravo/Openbravo-3.0MP21/build.xml:480: The following error occurred while executing this line:
480 <ant dir="${base.src}" target="compile.complete.development" inheritAll="true" inheritRefs="true" />
/home/pos/sourcecode_openbravo/Openbravo-3.0MP21/src/build.xml:874: The following error occurred while executing this line:
874 <jvmarg line="${env.CATALINA_OPTS}" />
/home/pos/sourcecode_openbravo/Openbravo-3.0MP21/src/build.xml:880: Directory
880 <jvmarg value="-Djava.io.tmpdir=${env.CATALINA_BASE}/temp" />
/var/lib/tomcat6/webapps/openbravo/WEB-INF/lib creation was not successful for an unknown reason
Any help would be appreciated. Thanks.
Sounds like a permission problem.
See the related section 'Permission issues' in openbravo wiki
EDIT
for the remaining issues, i believe the properties base.src, CATALINA_OPTS and CATALINA_BASE are not set properly. Check this via :
<echo>
$${base.src} => ${base.src}
$${env.CATALINA_OPTS} => ${env.CATALINA_OPTS}
$${env.CATALINA_BASE} => ${env.CATALINA_BASE}
</echo>
or simply output all available properties use :
<echoproperties/>
also consider, before using ${env.whatever} you need to use :
<property environment="env"/>
before !
/var/lib/tomcat6/webapps/openbravo/WEB-INF/lib creation was not successful for an unknown reason
Give the permission to webapps folder
sudo chmod -R 777 /var/lib/tomcat6/webapps/
/var/lib/tomcat6/webapps/openbravo/WEB-INF/lib creation was not
successful for an unknown reason
it seem permission problem. It is important to always us the correct user account to start / stop tomcat!
Conceptually there are two user accounts involved in working with Openbravo:
command-line user used to work with files & compile Openbravo
user account used by Apache Tomcat service
There are several overlapping areas in which one of the accounts needs to access and modify files from the other account in both directions.
To avoid any problems Openbravo strongly recommends to run Apache Tomcat services with the same user account which is used on command line. As that way the above topic will be perfectly solved easily.
source: http://wiki.openbravo.com/wiki/Installation/Custom/Apache_Tomcat

Ant scp task failure

I have one requirement: copy local files to remote system.
I have done the following:
downloaded jsch-0.1.44.jar and copied to lib folder of Ant
set the path and every thing
My buildfile is:
<project name="ImportedBuild" default="all">
<target name="copyFileToRemote">
<echo>2222222222 copyFileToRemote Examples:::::::::::::</echo>
<scp file="sample.txt" todir="${username}:${password}#${hostname}:/shared"/>
</target>
</project>
When I run Ant, I get this error:
BUILD FAILED com.jcraft.jsch.JSchException: reject HostKey: 10.184.74.168
at com.jcraft.jsch.Session.checkHost(Session.java:712)
at com.jcraft.jsch.Session.connect(Session.java:313)
at com.jcraft.jsch.Session.connect(Session.java:154)
at org.apache.tools.ant.taskdefs.optional.ssh.SSHBase.openSession(SSHBase.java:212)
at org.apache.tools.ant.taskdefs.optional.ssh.Scp.upload(Scp.java:291)
at org.apache.tools.ant.taskdefs.optional.ssh.Scp.execute(Scp.java:203)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
... etc ...
Any ideas how to resolve this?
According to the Ant scp task docs, trust attribute:
This trusts all unknown hosts if set
to yes/true. Note If you set this to
false (the default), the host you
connect to must be listed in your
knownhosts file, this also implies
that the file exists.
The trust attribute is not used in your task call, so it appears that the host (10.184.74.168) is not in your knownhosts file. Suggest you add trust="true", or add the host to the knownhosts file.
Be sure your ~/.ssh/known_hosts file is using un-hashed hostnames; if the lines start |1|base64data..., JSch appears unable to parse them. Create lines of the format hostname[,hostname|ip]* ssh-keytype base64data....
See man 8 sshd on the precise format of known_hosts, and tips on where to find the host's public key.

Resources