I'm setting up a jenkins job to build and deploy a Zend Framework 2 php application.
In my ant build script I've defined a lint job for validating php files.
The build job failed because lint detected an error in a ZF2 library file.
This is the output generated by lint:
[apply] PHP Fatal error: Constructor Zend\Captcha\Factory::factory() cannot be static in /var/lib/jenkins/workspace/XXX/vendor/zendframework/zendframework/library/Zend/Captcha/Factory.php on line 90
[apply] Errors parsing /var/lib/jenkins/workspace/XXX/vendor/zendframework/zendframework/library/Zend/Captcha/Factory.php
Does anybody know why the validation of Zend/Captcha/Factory.php fails ?
The ANT Task looks like this:
<target name="lint" description="Perform syntax check of sourcecode files">
<apply executable="php" failonerror="true">
<arg value="-l" />
<fileset dir="${basedir}/">
<include name="**/*.php" />
<modified />
</fileset>
<fileset dir="${basedir}/tests">
<include name="**/*.php" />
<modified />
</fileset>
</apply>
</target>
Your problem is because Zend Framework requires php 5.3.3 or later. Since your Jenkins box uses 5.3.2, this give a variety of problems. One of them is apparently the error you have now.
I think you haven't noticed the error before because on the development system you have a 5.3.3+ install. Try to update your testing environment to a newer version of php, that will remove this particular problem.
Update
To clarify my answer a bit, there is one backwards compatibility break in php 5.3.3 which comes back in your environment. Check this changelog and particularly this statement:
Backwards incompatible change:
Methods with the same name as the last element of a namespaced class name will no longer be treated as constructor. This change doesn't affect non-namespaced classes.
<?php
namespace Foo;
class Bar {
public function Bar() {
// treated as constructor in PHP 5.3.0-5.3.2
// treated as regular method in PHP 5.3.3
}
}
?>
There is no impact on migration from 5.2.x because namespaces were only introduced in PHP 5.3.
In the case of Zend\Captcha\Factory, there is a method factory() which is static so you can call Zend\Captcha\Factory::factory(). On php 4 and 5 up to 5.3.2, this method is also parsed as the constructor for the factory. And constructors cannot be static.
A linter will give you a fatal error for this case.
Related
I am working on MobileFirst Platform version7 using ant script to build the project .war, .wlapp, .adapter.
Everything was working fine while our project was a hybrid one. Now the project is migrated to native-iOS in.
I am using following code to build .wlapp.
<target name="build-wlapp">
<app-builder worklightServerHost="localhost:10080"
applicationFolder="//Users/admin/Documents/workspace/NewProj/apps/Try"
environments="iOSnative"
nativeProjectPrefix="NewProj"
outputFolder="/Users/admin/Documents/workspace/NewProj/bin"/>
it is throwing below error:
build.xml:66: Failed building application: The build could not be
completed due to invalid application-descriptor.xml.(cvc-elt.1: Cannot
find the declaration of element 'nativeIOSApp'.)
I am not getting where the flaw is...
Assuming the application-descriptor.xml you posted in your comment is complete, it looks like you have a stray semicolon after your xmlns declaration. That's not valid XML. Not sure how it got like that (check your source control system?), but you probably need to remove/revert it.
Sorry For the Wrong answer first.
You were using the wrong code to generate the .wlapp file the ant script is below.
<project default="change">
<target name="change">
<taskdef resource="com/worklight/ant/defaults.properties">
<classpath>
<pathelement location="worklight-ant-builder.jar"/>
</classpath>
</taskdef>
<native-app-builder
sourceFolder="C:\Workspace\Test\apps\Test" DestinationFolder="bin"
worklightServerHost="http://111.111.111.111:10080">
</native-app-builder>
</target>
</project>
If I pass a variable to ant by doing
ant -Dsomething=blah
How can I refer to it in my build.xml? I tried #something# and ${something} but neither seem to work.
Ultimately what I am trying to do is set some properties (versions) at compile time.
update: the problem of course turned out to be somewhere else - accepting the most complete looking answer with examples
Don't you hate it when you over think these things:
<project name="test">
<echo message="The value of foo is ${foo}"/>
</project>
Now, I'll run my program. Notice that I never defined a value for property foo in my build.xml. Instead, I'll get it from the command line:
$ ant -Dfoo=BAR_BAR_FOO
test:
[echo] The value of foo is BAR_BAR_FOO
BUILD SUCCESSFUL
time: 0 seconds
See. Nothing special at all. You treat properties set on the command line just like normal properties.
Here's where the fun comes in. Notice that I've defined the property foo in my build.xml this time around:
<project name="test">
<property name="foo" value="barfu"/>
<echo message="The value of foo is ${foo}"/>
</project>
Now watch the fun:
$ ant
test:
[echo] The value of foo is barfu
BUILD SUCCESSFUL
time: 0 seconds
Now, we'll set the property foo on the command line:
$ ant -Dfoo=BAR_BAR_FOO
test:
[echo] The value of foo is BAR_BAR_FOO
BUILD SUCCESSFUL
time: 0 seconds
See the command line overrides the value I set in the build.xml file itself. This way, you can have defaults that can be overwritten by the command line parameters.
It sounds like you want to do something like the following:
<mkdir dir="build/src"/>
<copy todir="build/src" overwrite="true">
<fileset dir="src" includes="**/*.java"/>
<filterset>
<filter token="VERSION" value="${version}"/>
</filterset>
</copy>
...which will cause your source to get copied, replacing #VERSION#:
public class a { public static final String VERSION = "#VERSION#"; }
...and then include build/src in your javac src.
That said, I don't recommend this approach since the source copy step is expensive, and it will undoubtedly cause confusion. In the past, I've stored a version.properties file in my package with version=x.y. In my Java code, I used Class.getResourceAsStream("version.properties") and java.util.Properties. In my build.xml, I used <property file="my/pkg/version.properties"/> so that I could create an output-${version}.jar.
${argsOne} works for me and is easily referenced if the invoking command is
ant -DargsOne=cmd_line_argument
Ant documentation also says so. This should work, try running with ant -debug and paste the output.
I have been having trouble deploying liferay portlets and themes from the command line with ant deploy;
sample execution:
pwd: C:\liferay-plugins-sdk\themes
create.bat deep-blue "Deep Blue"
cd deep-blue-theme
ant deploy
-> Buildfile: C:\liferay-plugins-sdk\themes\deep-blue-theme\build.xml
-> compile:
-> BUILD FAILED
-> C:\liferay-plugins-stk\themes\build-common-theme.xml:172: C:\liferay-plugins-sdk\themes\deep-blue-theme\liferay-portal-6.0.6 omcat-6.0.29webappsROOT\html\themes_unstyled does not exist.
the problem appears to be with the bold section and how the path is obviously incorrect; where is this directory being set?
edit:
the problem was my app.server.dir in build.{username}.properties
The error is a result of the ant build not being able to find a Liferay installation (which contains items needed by the SDK).
By default, the build properties in the SDK are set up on the assumption that your setup looks like this:
- Your Development Directory
- bundles
- data
- deploy
- license
- tomcat-6.0.29
- liferay-plugins-sdk
Where bundles contains a Liferay bundle distribution, including the bundled Tomcat server.
You can see this setup in the build.properties file at the root level of your SDK.
#
# Specify the paths to an unzipped Tomcat bundle.
#
app.server.type=tomcat
app.server.dir=${project.dir}/../bundles/tomcat-6.0.29
app.server.deploy.dir=${app.server.dir}/webapps
app.server.lib.global.dir=${app.server.dir}/lib/ext
app.server.portal.dir=${app.server.dir}/webapps/ROOT
The recommended way to change this is not to edit this section of build.properties, but to create overriding entries in a new file, called build.username.properties. (where username is your user name on your computer account).
As you say in the comment to kirkz's answer, you have already set your build.connor.properties: You obviously have used backslash in there. Here \t is short for the tab character. This explains what you see: ...liferay-portal-6.0.6 omcat... (there's a tab between 6.0.6 and omcat)
Do only use forward-slash in properties files (when you refer to file names, no matter if you're on windows or on any other platforms)
I think to solve this issue just for now. To check weather you are getting unsuccessful build or not you can try this solution:
I have just used the static liferay path in this solution.
<elseif>
<equals arg1="${theme.parent}" arg2="classic" />
<then>
<copy todir="docroot" overwrite="true">
<fileset
dir="C:/Liferay/liferay-portal-6.2-ce-ga2/tomcat-7.0.42/webapps/ROOT/html/themes/classic"
excludes="_diffs/**,templates/**"
/>
</copy>
<copy todir="docroot/templates" overwrite="true">
<fileset
dir="C:/Liferay/liferay-portal-6.2-ce-ga2/tomcat-7.0.42/webapps/ROOT/html/themes/classic/templates"
includes="*.${theme.type}"
/>
</copy>
</then>
</elseif>
After setting up this code in your build-common-theme.xml file you will NOT get omcat-6.0.29webappsROOT\html\themes_unstyled error at least.
I'm in the process of modifying an Ant script (currently in use from within MyEclipse) to work from the command line. I'm doing this so anyone can check out the project and build it without MyEclipse. The problem I'm running into is that MyEclipse includes the dependencies behind the scenes. It does this by looking at the workspace's Ant configuration and compiling the classpath based on the selected libraries in the preferences dialog. Long story short, I need to take those dependencies and make the script smart enough to include them on its own, without the help of MyEclipse.
The tasks that are giving me a headache are the sshexec and scp tasks. They are optional ant tasks that require a version of jsch to run. I removed jsch from MyEclipse's Ant classpath and added it to a lib folder in the project itself (lib/dev). MyEclipse immediately complained that the SSHExec class could not find the dependent class, com.jcraft.jsch.UserInfo which is part of jsch-0.1.44.jar.
I don't see a way to set the classpath for Ant from within the build script. I have the following code, which adds a path element to the script, but I don't think Ant uses this unless explicitly associated to a task or another element.
<path id="web-jars">
<fileset dir="${web-lib}">
<include name="**/*.jar" />
</fileset>
<fileset dir="${app-lib}"> <!-- this is where jsch resides -->
<include name="**/*.jar" />
</fileset>
</path>
It seems that I need to use taskdef to define the sshexec and scp tasks:
<taskdef name="sshexec" classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec"
classpathref="web-jars"/>
MyEclipse complains about this, "taskdef A class needed by class org.apache.tools.ant.taskdefs.optional.ssh.SSHExec cannot be found: com/jcraft/jsch/UserInfo"
It's clearly in the classpathref, web-jars. And I can't run anything in the script because of this malformed or misconfigured taskdef.
The problem here is that the SSHExec class is loaded from a classloader which itself has no access to your web-jars class loader. Supplying this classpath for the taskdef does not change this. Each class can only load classes from its own classloader and any parent class loaders, but the web-jars classloader is not a parent class loader of SSHExec's class loader (it is likely the other way around, since SSHExec seems to be found here).
It looks like this:
ClassLoader web-jars -------------> application CL -------------> bootstrap CL
taskdef
=> look for SSHExec here
=> look first in parent class loader
=> look for SSHExec here
=> look first in parent class loader
=> look for SSHExec here
=> not found
=> look in our own classpath
=> found, load the class
=> it somehow uses interface UserInfo
=> look for UserInfo here
=> look first in parent class loader
=> look for UserInfo here
=> not found
=> look in our own classpath
=> not found, throw exception.
The VM has no idea to look for UserInfo (and the other JSch classes) in the web-jars classloader.
I suppose the SSHExec task is somewhere in the usual ant classpath, i.e. loaded by the application class loader. Then removing SSHExec from ant's classpath (or adding jsch.jar to it) seems to be the only solution here.
Create ~/.ant/lib and copy jsch.jar in there as part of the build initialisation. Any tasks which do scp/sshexec work should depend on this init target.
<target name="init">
<property name="user.ant.lib" location="${user.home}/.ant/lib"/>
<mkdir dir="${user.ant.lib}"/>
<copy todir="${user.ant.lib}">
<fileset dir="${basedir}/build/tools" includes="jsch-*.jar"/>
</copy>
</target>
<target name="mytarget" depends="init">
<scp todir="user#host"><fileset dir="..."/></scp>
</target>
The Ant within Eclipse unfortunately won't pick this up immediately as it does not read ~/.ant/lib on every execution; After running mytarget within Eclipse once and watching it fail, then go to:
Window>Preferences>Ant>Runtime and press Restore Defaults - this will add any .jar files from ~/.ant/lib to the Global Entries section and you should be good to go.
My PC is currently set up as Japanese for testing purposes. If my java project has a compilation error the message is reported in Japanese.
e.g.
Compiling 1 source file to [...directory...]
[...class...].java:172: シンボルを見つけられません。
I would prefer to see the errors in english.
Without using ant the fix for this is to use
javac -J-Duser.language=en [..java files...]
which makes javac give english error messages (the -J tells javac to pass the rest of the argument to java)
My question is: how do I pass this to ant
[editted to remove options I tried that didn't work]
Try adding a <compilerarg> to your <javac> call. For example:
<javac srcdir="${src.dir}" destdir="${classes.dir}" fork="true">
<compilerarg value="-J-Duser.language=en"/>
<compilerarg value="-J-Duser.country=GB"/>
</javac>
EDIT Fixed the arg values. Also, this only works if the compiler is forked; I updated the example to reflect that.