Your browser was unable to load all of the resources. They may have been blocked by your firewall, proxy or browser configuration.
Press Ctrl+F5 or Ctrl+Shift+R to have your browser try again.

build QB 16 src #4695

idoharel ·

Hi,

I am trying to build QB source version 16 using Ant (ant -f build.xml under the system/build folder).

My environment is set to Java 21, and our repository is compiled with Java 21.

Previously we used QB14 with Java 8, but it seems the newer QB version now requires Java 11 to run.

Is there any way to compile it with Java 21 instead?

I noticed in the Ant configuration that the Java source level is set to 11.

  • replies 2
  • views 21
  • stars 0
idoharel ·

update,
src compilr with this build.xml:

<property file="system/build/build.properties"/>
<property name="javadoc" value="yes"/>

<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy">
	<classpath>
		<fileset dir="com.pmease.quickbuild/lib" includes="*groovy*.jar"/>
	</classpath>
</taskdef>

<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask">
	<classpath location="system/build/lib/xmltask.jar"/>
</taskdef>

<target name="stage.plugin">
	<mkdir dir="stage/plugins/${pluginDir}"/>
	<copy todir="stage/plugins/${pluginDir}">
		<fileset dir="${pluginDir}" excludes=".project, .classpath, build.properties, .settings/**, 
			src/**, bin/**, test/**, test-src/**, test-out/**, testout/**, testbin/**, test-bin/**, 
			test-result/**, **/*.java, **/*.class"/> 
	</copy>
	<copy todir="stage/classpath/lib" flatten="true">
		<fileset dir="stage/plugins/${pluginDir}" includes="**/*.jar"/>
	</copy>
</target>
	
<target name="compile.plugin">
    <javac destdir="stage/plugins/${pluginDir}" encoding="UTF-8" debug="on" source="11" target="11" includeAntRuntime="false">
        <src path="${pluginDir}/src"/>
        <classpath>
        	<fileset dir="stage/classpath/lib" includes="**/*.jar"/>
        	<pathelement location="stage/classpath/classes"/>
        </classpath>
    </javac>		
	<copy todir="stage/plugins/${pluginDir}">
		<fileset dir="${pluginDir}/src" excludes="**/*.java"/>
	</copy>
	<copy todir="stage/classpath/classes">
		<fileset dir="stage/plugins/${pluginDir}" includes="**/*.class"/>
	</copy>
</target>

<target name="jar.plugin">
	<xmltask source="${pluginDir}/.classpath" dest="stage/plugins/${pluginDir}/.classpath">
		<insert path="/classpath">
				<![CDATA[  
	<classpathentry exported="true" kind="lib" path="${pluginId}_${pluginVersion}.jar">
		<attributes>
			<attribute name="javadoc_location" value="jar:platform:/resource/com.pmease.quickbuild.bootstrap/javadoc.zip!/"/>
		</attributes>
	</classpathentry>
				]]> 				
		</insert>
		<remove path="/classpath/classpathentry[@kind='src']"/>			
	</xmltask>
	<groovy>
		if (properties["pluginId"] == "com.pmease.quickbuild") {
			new AntBuilder().copy(file:"${properties['basedir']}/stage/asset/release", 
				tofile:"${properties['basedir']}/stage/plugins/com.pmease.quickbuild/com/pmease/quickbuild/release")
		}
	</groovy>
    <jar destfile="stage/plugins/${pluginId}_${pluginVersion}.jar" manifest="stage/plugins/${pluginDir}/META-INF/MANIFEST.MF">
    	<fileset dir="stage/plugins/${pluginDir}"/>
    </jar>
	<groovy>
		def dir = new File(properties["basedir"], "stage/plugins/${properties['pluginDir']}")
		for (int i = 0; i &lt; 10; i++) {
			System.gc()
			Thread.sleep(1000)
			try {
				new AntBuilder().delete(dir: dir.absolutePath, includeEmptyDirs: true)
				break
			} catch (Exception e) {
				if (i == 9) throw e
			}
		}
	</groovy>
</target>
<target name="jar.bootstrap">
	<replace file="stage/plugins/${pluginDir}/META-INF/MANIFEST.MF" token=".," value="${pluginId}_${pluginVersion}.jar," />
    <jar destfile="stage/plugins/${pluginDir}/${pluginId}_${pluginVersion}.jar" manifest="stage/plugins/${pluginDir}/META-INF/MANIFEST.MF">
    	<fileset dir="stage/plugins/${pluginDir}">
    		<exclude name="lib/**"/>
    		<exclude name="javadoc.zip"/>
    		<exclude name="*.txt"/>
    	</fileset>
    </jar>
	<xmltask source="${pluginDir}/.classpath" 
			dest="stage/plugins/${pluginDir}/.classpath">
		<insert path="/classpath">
			<![CDATA[  
<classpathentry exported="true" kind="lib" path="${pluginDir}/${pluginId}_${pluginVersion}.jar">
	<attributes>
		<attribute name="javadoc_location" value="jar:platform:/resource/${pluginDir}/javadoc.zip!/"/>
	</attributes>
</classpathentry>
			]]> 				
		</insert>
		<remove path="/classpath/classpathentry[@kind='src']"/>			
	</xmltask>
	<delete dir="stage/plugins/${pluginDir}/com"/>
	<delete dir="stage/plugins/${pluginDir}/org"/>
</target>

<target name="assemble.plugins">
	<mkdir dir="stage/classpath/lib"/>
	<mkdir dir="stage/classpath/classes"/>
	<groovy>
		def pluginDependencies = new HashMap()
		def pluginDirs = new HashMap()
		def pluginVersions = new HashMap()
		for (each in new File(properties["basedir"]).listFiles()) {
			def manifestFile = new File(each, "META-INF/MANIFEST.MF")
			if (manifestFile.exists()) {
				def attrs
				manifestFile.withInputStream {
					stream -> attrs = new java.util.jar.Manifest(stream).getMainAttributes()
				}
				def pluginId = attrs.getValue("Bundle-SymbolicName")
				if (pluginId != null)
				if (pluginId.trim().length() != 0) {
					def pos = pluginId.indexOf(';')
					if (pos != -1)
						pluginId = pluginId.substring(0, pos)
					pluginDirs.put(pluginId, each)
					pluginVersions.put(pluginId, attrs.getValue("Bundle-Version"))
					def dependencies = new HashSet()
					String required = attrs.getValue("Require-Bundle")
					if (required != null) {
						for (partial in required.split(",")) {
							partial = partial.trim()
							if (partial.length() == 0)
								continue;
							pos = partial.indexOf(';')
							if (pos != -1)
								partial = partial.substring(0, pos).trim()
							dependencies.add(partial);		
						}
					}
					pluginDependencies.put(pluginId, dependencies)
				}
			}
		}
		for (pluginId in pluginDependencies.keySet()) {
			for (dependency in pluginDependencies.get(pluginId)) {
				if (!pluginDependencies.containsKey(dependency))
					throw new RuntimeException("Plugin '" + pluginId + "' requires non-existant plugin '" + dependency + "'.")
			}
		}
		
		def sortedPlugins = new ArrayList()
		
		def dependencyIds = new HashMap()
		for (entry in pluginDependencies.entrySet()) 
			dependencyIds.put(entry.getKey(), new HashSet(entry.getValue()))

		while (!dependencyIds.isEmpty()) {
			Set leafs = new HashSet()
			for (key in dependencyIds.keySet()) {
				if (dependencyIds.get(key).isEmpty()) {
					leafs.add(key)
					sortedPlugins.add(key)
				}
			}
			if (leafs.isEmpty()) {
				Set unprocessed = new HashSet()
				for (id in dependencyIds.keySet())
					unprocessed.add(id);
				throw new RuntimeException("Unable to process dependencies: " + unprocessed 
						+ ". This is either because circular exists in these dependencies, or because " 
						+ "some of these dependencies depends on non-existent dependencies.")
			}
			for (key in leafs) 
				dependencyIds.remove(key)
			for (value in dependencyIds.values())
				value.removeAll(leafs)
		}		
		
		for (pluginId in sortedPlugins) {
			properties["pluginDir"] = pluginDirs.get(pluginId).name
			ant.project.executeTarget("stage.plugin")
			if (new File(pluginDirs.get(pluginId), "src").exists()) 
				ant.project.executeTarget("compile.plugin")
			properties["pluginId"] = pluginId
			properties["pluginVersion"] = pluginVersions.get(pluginId)
			if (pluginId != "com.pmease.quickbuild.bootstrap")
			if (pluginId != "com.pmease.quickbuild.libs") 
				ant.project.executeTarget("jar.plugin")
			if (pluginId == "com.pmease.quickbuild.bootstrap")
				ant.project.executeTarget("jar.bootstrap")
		
			if (pluginId == "com.pmease.quickbuild.equinoxadapter")
				properties["equinoxadapterVersion"] = pluginVersions.get(pluginId)
		}
	</groovy>
	
	<copy file="stage/plugins/com.pmease.quickbuild.equinoxadapter_${equinoxadapterVersion}.jar" 
		tofile="stage/framework/org.eclipse.osgi_adapter.jar"/>
	<delete dir="stage/classpath"/>
	<mkdir dir="stage/plugins/site"/>
	<touch file="stage/plugins/site/PUT_YOUR_CUSTOM_PLUGINS_HERE"></touch>
</target>

<target name="license">
	<delete dir="stage/license"/>
	<mkdir dir="stage/license/lib"/>
	<copy todir="stage/license/lib">
		<fileset dir="com.pmease.quickbuild.bootstrap/lib" 
			includes="commons-codec*.jar, commons-lang*.jar"/>
	</copy>
	<mkdir dir="stage/license/classes"/>
    <javac destdir="stage/license/classes" debug="on" source="11">
        <src path="com.pmease.quickbuild/src"/>
		<include name="com/pmease/quickbuild/license/**/*.java"/>
        <classpath>
        	<fileset dir="stage/license/lib" includes="*.jar"/>
        </classpath>
    </javac>		
    <jar destfile="stage/license/quickbuild-license.jar">
    	<fileset dir="stage/license/classes"/>
    </jar>
	<delete dir="stage/license/classes"/>

	<echo message="License jars built successfully under ${basedir}/stage/license"/>
</target>

<target name="stage">  
	<groovy>
		properties['build.date']=new java.util.Date().getTime();			
		def osname = System.getProperty("os.name").toLowerCase();
		if (osname.contains("windows"))
			properties['os.family']="windows";
		else if (osname.contains("linux"))
			properties['os.family']="linux";
		else if (osname.contains("mac"))
			properties['os.family']='macosx';
		else
			properties['os.family']='others';
	</groovy>
	
	<fail message="QuickBuild can only be built on windows, linux and macosx." unless="os.family"/>
	
	<mkdir dir="stage"/>
	<copy todir="stage">
		<fileset dir="system" includes="*.txt" excludes="source-*.txt"/>
		<filterset>
			<filter token="build.version" value="${build.version}"/>
			<filter token="docroot" value="${docroot}"/>
		</filterset>
	</copy>
	<mkdir dir="stage/3rdparty-licenses"/>
	<copy todir="stage/3rdparty-licenses">
		<fileset dir="system/3rdparty-licenses"/>
	</copy>
	<mkdir dir="stage/logs"/>
	<touch file="stage/logs/console.log"/>
	<copy todir="stage/bin">
		<fileset dir="system/bin" includes="**/*wrapper*"/>
	</copy>
	<copy tofile="stage/bin/server.bat" file="system/bin/quickbuild.bat">
        <filterset>
            <filter token="app.name" value="quickbuild"/>
            <filter token="app.long.name" value="QuickBuild Server"/>
            <filter token="app.description" value="QuickBuild Server"/>
        </filterset>
	</copy>
	<copy tofile="stage/bin/server.sh" file="system/bin/quickbuild.sh">
        <filterset>
            <filter token="app.name" value="quickbuild"/>
            <filter token="app.long.name" value="QuickBuild Server"/>
            <filter token="app.description" value="QuickBuild Server"/>
        </filterset>
	</copy>
	<copy todir="stage/asset">
		<fileset dir="system/asset"/>
	</copy>
	<copy todir="stage/framework">
		<fileset dir="system/framework"/>
	</copy>
    <mkdir dir="stage/sampledb"/>
	<propertyfile file="stage/asset/release">
        <entry key="version" value="${build.version}"/>
		<entry key="build" value="${build.number}"/>
		<entry key="date" value="${build.date}"/>
		<entry key="docroot" value="${docroot}"/>
    </propertyfile>

	<antcall target="assemble.plugins"/>
	
	<groovy>
		wrapper_classpath="";
		int index=1;
		new File("${properties['basedir']}/stage/plugins/com.pmease.quickbuild.bootstrap").listFiles().each() {
			if (it.name.endsWith(".jar")) { 
				wrapper_classpath += "wrapper.java.classpath." + index + "=../plugins/com.pmease.quickbuild.bootstrap/" + it.name + "\r\n";
				index++;
			}
		}
		new File("${properties['basedir']}/stage/plugins/com.pmease.quickbuild.bootstrap/lib").listFiles().each() {
			if (it.name.endsWith(".jar")) { 
				wrapper_classpath += "wrapper.java.classpath." + index + "=../plugins/com.pmease.quickbuild.bootstrap/lib/" + it.name + "\r\n";
				index++;
			}
		}
		properties['wrapper.classpath']=wrapper_classpath;
	</groovy>
	
	<copy todir="stage/bin">
		<fileset dir="system/bin" includes="*.bat, *.sh" excludes="quickbuild.bat, quickbuild.sh"/>
	</copy>
	
	<copy todir="stage/conf">
		<fileset dir="system/conf"/>
        <filterset>
            <filter token="app.name" value="quickbuild"/>
            <filter token="app.long.name" value="QuickBuild Server"/>
            <filter token="app.description" value="QuickBuild Server"/>
        	<filter token="classpath" value="${wrapper.classpath}"/>
        	<filter token="initmemory" value="512"/>
        	<filter token="maxmemory" value="2048"/>
        	<filter token="docroot" value="${docroot}"/>
        </filterset>
	</copy>
	
	<chmod dir="stage/bin" perm="+x" includes="**/*.sh, wrapper-*" excludes="*.dll, *.exe"/>    	    	

	<!-- agent -->
	<delete dir="stage/agent"/>
	<copy tofile="stage/agent/buildagent/wrapper.conf" file="system/conf/wrapper.conf">
        <filterset>
            <filter token="app.name" value="buildagent"/>
            <filter token="app.long.name" value="QuickBuild Build Agent"/>
            <filter token="app.description" value="QuickBuild Build Agent"/>
        	<filter token="classpath" value="${wrapper.classpath}"/>
        	<filter token="initmemory" value="256"/>
        	<filter token="maxmemory" value="2048"/>
        </filterset>
	</copy>
	<copy tofile="stage/agent/useragent/wrapper.conf" file="system/conf/wrapper.conf">
        <filterset>
            <filter token="app.name" value="useragent"/>
            <filter token="app.long.name" value="QuickBuild User Agent"/>
            <filter token="app.description" value="QuickBuild User Agent"/>
        	<filter token="classpath" value="${wrapper.classpath}"/>
        	<filter token="initmemory" value="256"/>
        	<filter token="maxmemory" value="1024"/>
        </filterset>
	</copy>
	
	<copy file="system/bin/config.sh" tofile="stage/agent/config.sh"/>
	<copy file="system/bin/config.bat" tofile="stage/agent/config.bat"/>
	<copy file="system/bin/quickbuild.sh" tofile="stage/agent/buildagent/agent.sh">
        <filterset>
            <filter token="app.name" value="buildagent"/>
            <filter token="app.long.name" value="QuickBuild Build Agent"/>
            <filter token="app.description" value="QuickBuild Build Agent"/>
        </filterset>
	</copy>
	<copy file="system/bin/quickbuild.bat" tofile="stage/agent/buildagent/agent.bat">
        <filterset>
            <filter token="app.name" value="buildagent"/>
            <filter token="app.long.name" value="QuickBuild Build Agent"/>
            <filter token="app.description" value="QuickBuild Build Agent"/>
        </filterset>
	</copy>
	<copy file="system/bin/quickbuild.sh" tofile="stage/agent/useragent/agent.sh">
        <filterset>
            <filter token="app.name" value="useragent"/>
            <filter token="app.long.name" value="QuickBuild User Agent"/>
            <filter token="app.description" value="QuickBuild User Agent"/>
        </filterset>
	</copy>
	<copy file="system/bin/quickbuild.bat" tofile="stage/agent/useragent/agent.bat">
        <filterset>
            <filter token="app.name" value="useragent"/>
            <filter token="app.long.name" value="QuickBuild User Agent"/>
            <filter token="app.description" value="QuickBuild User Agent"/>
        </filterset>
	</copy>		    	
	    	
	<!-- dev -->
	<copy todir="stage/dev">
		<fileset dir="system/dev" excludes="**/samples.*, **/*.class, **/*.txt, **/*.xml"/>
	</copy>
	<copy todir="stage/dev">
		<fileset dir="system/dev" includes="**/*.txt"/>
		<filterset>
			<filter token="docroot" value="${docroot}"/>
		</filterset>
	</copy>
	<copy todir="stage/dev/plugin/samples">
		<fileset dir=".">
			<include name="com.example.*/**"/>
			<include name="com.pmease.quickbuild.plugin.artifact/**"/>
			<include name="com.pmease.quickbuild.plugin.scm.subversion/**"/>
			<include name="com.pmease.quickbuild.plugin.authenticator.ldap/**"/>
			<include name="com.pmease.quickbuild.plugin.notifier.msn/**"/>
			<include name="com.pmease.quickbuild.plugin.builder.ant/**"/>
			<include name="com.pmease.quickbuild.plugin.tracker.redmine/**"/>
			<include name="com.pmease.quickbuild.plugin.report.boosttest/**"/>
			<exclude name="**/bin/**"/>
		</fileset>
		<fileset dir="system/dev/plugin" includes="*.xml"/>
	</copy>
	<groovy>
		if (properties["javadoc"] == "yes")
			ant.project.executeTarget("javadoc");
	</groovy>    	    	
</target>
	
<target name="collectsrc.plugin">
	<copy todir="stage/dev/plugin/src">
		<fileset dir="${plugin.dir}/src" includes="**/*.java"></fileset>
	</copy>
</target>

<target name="javadoc">
	<mkdir dir="stage/doclets"/>
    <javac destdir="stage/doclets" debug="on" source="11">
        <src path="com.pmease.quickbuild.doclets/src"/>
    	<classpath>
    		<fileset dir="com.pmease.quickbuild.bootstrap" includes="**/*.jar"/>
    	</classpath>
    </javac>	
	<copy todir="stage/doclets">
		<fileset dir="com.pmease.quickbuild.doclets/src" excludes="**/*.java"/>
	</copy>
	
	<mkdir dir="stage/dev/plugin/javadoc"/>
	<mkdir dir="stage/dev/plugin/src"/>

	<groovy>
		for (each in new File(properties["basedir"]).listFiles()) {
			if (new File(each, "src").exists()) {
				properties["plugin.dir"] = each.name
				ant.project.executeTarget("collectsrc.plugin")
			}
		}
	</groovy>
	
    <javadoc destdir="stage/dev/plugin/javadoc" source="11" useexternalfile="true" author="true" 
    		version="true" use="false" windowtitle="QuickBuild API" maxmemory="512m">
    	<doclet name="com.pmease.quickbuild.doclets.standard.Standard">
    		<path>
    			<pathelement path="stage/doclets"/>
        		<fileset dir="com.pmease.quickbuild.bootstrap" includes="**/*.jar"/>
    		</path>
    	</doclet>
        <doctitle><![CDATA[<h1>QuickBuild</h1>]]></doctitle>
        <bottom><![CDATA[<i>Copyright &#169; 2005-2016 PMEase All Rights Reserved.</i>]]></bottom>
    	<fileset dir="stage/dev/plugin/src">
    		<include name="**/*.java"/>
			<exclude name="com/pmease/quickbuild/license/**"/>
			<exclude name="com/pmease/quickbuild/migration/qb1/**"/>
			<exclude name="com/pmease/quickbuild/test/**"/>
    		<exclude name="org/**"/>
    	</fileset>
    	<classpath>
    		<fileset dir="${basedir}" includes="**/*.jar"/>
    	</classpath>
    </javadoc>		
	<delete dir="stage/doclets"/>
	<zip destfile="stage/plugins/com.pmease.quickbuild.bootstrap/javadoc.zip" 
		basedir="stage/dev/plugin/javadoc"/>
</target>

<target name="package" depends="stage">
	<property name="package.name" value="quickbuild-${build.version}"/>
	<mkdir dir="package/${package.name}"/>
	<copy todir="package/${package.name}">
		<fileset dir="stage" excludes="dev/plugin/javadoc/**, dev/plugin/src/**"/>
	</copy>
	<zip destfile="package/${package.name}.zip">
		<zipfileset dir="package" includes="${package.name}/**/*"
			excludes="${package.name}/bin/*.sh, ${package.name}/bin/wrapper-*"/> 
		<zipfileset dir="package" 
			includes="${package.name}/bin/*.sh, ${package.name}/bin/wrapper-*"
			filemode="755"/> 
	</zip>
	<tar destfile="package/${package.name}.tar.gz" compression="gzip">
		<zipfileset dir="package" includes="${package.name}/**/*"
			excludes="${package.name}/bin/*.sh, ${package.name}/bin/wrapper-*"/> 
		<zipfileset dir="package" 
			includes="${package.name}/bin/*.sh, ${package.name}/bin/wrapper-*"
			filemode="755"/> 
	</tar>	
</target>

<target name="package.src">
	<mkdir dir="package/quickbuild-${build.version}-src"/>
	<copy todir="package/quickbuild-${build.version}-src">
		<fileset dir="." includes="com.pmease.quickbuild*/**, com.example.promptbean/**, system/**" 
			excludes="com.pmease.quickbuild*/bin/**, com.example.promptbean/bin/**, system/source-*.txt, 
			system/dev/restapi/samples/java/.metadata/**, system/dev/restapi/samples/java/samples/bin/**"/>
		<fileset dir="system" includes="source-*.txt"/>
	</copy>
	<zip destfile="package/quickbuild-${build.version}-src.zip">
		<zipfileset dir="package" includes="quickbuild-${build.version}-src/**"/> 
	</zip>
</target>

<target name="clean">
	<delete dir="stage"/>
	<delete dir="package"/>
</target>

and this command:

$env:ANT_OPTS="--add-opens java.xml/com.sun.org.apache.xpath.internal=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xpath.internal.objects=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.dtm=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.dtm.ref=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.utils=ALL-UNNAMED"; ant -f build.xml

java use:
java -version
java version "21.0.9" 2025-10-21 LTS
Java(TM) SE Runtime Environment (build 21.0.9+7-LTS-338)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.9+7-LTS-338, mixed mode, sharing)

robinshen ADMIN ·

Hi, QB16 only supports to be compiled with Java 11. To build, please run command "ant clean package" inside directory "system/build".