I have a custom MANIFEST.MF in my java-project in Eclipse.
When exporting the project to a jar, I choose
Use existing manifest from workspace
Extracting the .jar shows that eclipse generated its own manifest.
My manifest:
Manifest-Version: 1.0
Main-Class: de.somehow.tagPDF.Main
Class-Path: lib/iText-5.0.2.jar;lib/jxl.jar;lib/jai_codec.jar;lib/jai_core.jar
How can I fix this?
You can make use of a build.xml to build the jar file for you.
Then you just run the build.xml as a Ant task.
See
If you want the build.xml to run automatically every time you build your Eclipse project, you can add it to the Builders list.
See
Below is a sample build.xml where a custom manifest is used:
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." name="Example" default="run_build">
<property name="guiJar" value="../../Library/<jar-name>.jar"></property>
<target name="run_build" depends="delete_old_jar,create_dirs,create_manifest,copy_all_class_files,create_jar,delete_temp_dirs">
</target>
<target name="delete_old_jar">
<delete file="${guiJar}">
</delete>
</target>
<target name="create_dirs">
<mkdir dir="jar_temp" />
<mkdir dir="jar_temp/META-INF" />
</target>
<target name="delete_temp_dirs">
<delete dir="jar_temp">
</delete>
</target>
<target name="create_manifest">
<manifest file="jar_temp/META-INF/MANIFEST.MF">
<attribute name="Manifest-Version" value="1.0" />
<attribute name="Version" value="1.0.0" />
<attribute name="Company" value="Value" />
<attribute name="Project" value="Value" />
<attribute name="Java-Version" value="${java.version}" />
<attribute name="Class-Path" value="test.jar" />
<attribute name="Main-Class" value="com.Main" />
</manifest>
</target>
<target name="create_jar">
<jar destfile="${guiJar}" manifest="jar_temp/META-INF/MANIFEST.MF" basedir="jar_temp">
</jar>
</target>
<target name="copy_all_class_files">
<copy todir="jar_temp">
<fileset dir="classes">
<include name="*/**" />
</fileset>
</copy>
</target>
</project>
In eclipse 3.6.1.
Rigth click on your compiled project -> Export
Next you should choose Java - JAR File from the tree
In new form appeared after you select options don't click finish but 'Next'.
Third form will be 'JAR Manifest Specification' and there you can choose your manifest file instead of eclipse generated one.
Related
I have a Java project that uses SWT and compiles/runs perfectly.
When I try to compile via Ant, however, javac cannot find the SWT library despite the build.xml specifying the correct classpath.
The SWT library is located in C:\my_work\Eclipse\3.6-64\plugins\. As seen below (under the javac tags, this classpath is specified as such.
build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project default="run" name="My Project">
<target name="run" depends="compile">
<java classname="com.company.program.project">
<classpath path="staging\" location="C:\my_work\Eclipse\3.6-64\plugins\"/>
</java>
</target>
<target name="compile">
<javac includeantruntime="false" srcdir="./src" destdir="staging">
<classpath path="C:\my_work\Eclipse\3.6-64\plugins\"></classpath>
</javac>
</target>
<jar destfile="./build/jars/swtgui.jar" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="org.swtgui.MainGui" />
<attribute name="Class-Path" value="." />
</manifest>
<fileset dir="./bin/com/company/program/project" includes="**/*.class" />
<fileset dir="C:\my_work\Eclipse\3.6-64\plugins\" includes="org.eclipse.swt.win32.win32.x86_64_3.6.0.v3650b.jar" />
</jar>
<record name="./MyProject.log" loglevel="verbose" action="start"/>
The above gives me errors on import statements such as the following:
error: package org.eclipse.swt does not exist
import org.eclipse.swt.SWT;
^
Why does javac not find the SWT library when the classpath is correctly specified?
Also how can I find out where javac is looking? The logs -- even in verbose mode -- tell me nothing about where javac is trying to find these import statements.
SWT provides a separate Jar for standalone Java applications.
You can download the latest one from here - look at the 'SWT Binary and Source' section near the bottom of the page.
it seems <classpath path="C:\my_work\Eclipse\3.6-64\plugins\"></classpath> is not adding dependencies to compile classpath
this way works for me:
<target name="compile">
<javac includeantruntime="false" srcdir="./src" destdir="staging">
<classpath>
<fileset dir="C:\my_work\Eclipse\3.6-64\plugins">
<!-- <include name="**/*.jar" /> -->
<include name="org.eclipse.swt.*.jar" />
</fileset>
</classpath>
</javac>
</target>
I have 3 source trees rooted at:
/src/
/srcDriver/
/test/
But during the ANT build I have, which works great, except all three are placed into my production executable-jar, how do I remove srcDriver and test so they don't get compiled in?
here is my build.xml.
`
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="create_production_jar" name="Create Runnable Jar for Project company with Jar-in-Jar Loader">
<!--this file was created by Eclipse Runnable JAR file Export Wizard-->
<!--ANT 1.7 is required-->
<!--define folder properties-->
<property name="dir.buildfile" value="."/>
<property name="dir.workspace" value="${dir.buildfile}/../.."/>
<property name="dir.jarfile" value="${dir.buildfile}/target/jar"/>
<target name="create_production_jar" description="Create Production Jar">
<jar destfile="${dir.jarfile}/COMPANYNAMEApplicationServer.jar">
<manifest>
<attribute name="Main-Class" value="org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader"/>
<attribute name="Rsrc-Main-Class" value="com.COMPANYNAME.PRODUCT.ApplicationServer"/>
<attribute name="Class-Path" value="."/>
<attribute name="Rsrc-Class-Path" value="./ XXX.YYY.ZZZ1.jar ..........(SOME 300 MORE DEPENDENCIES).......... XXX.YYY.ZZZ2.jar"/>
</manifest>
<zipfileset src="jar-in-jar-loader.zip"/>
<fileset dir="${dir.buildfile}/target/classes"/>
<zipfileset dir="C:/Mnt/Users/jamesdmcmillian/.m2/repository/io/dropwizard/dropwizard-util/0.8.0" includes="dropwizard-util-0.8.0.jar"/>
..........(SOME 300 MORE DEPENDENCIES)..........
<zipfileset dir="C:/Mnt/Users/jamesdmcmillian/.m2/repository/com/fasterxml/jackson/module/jackson-module-afterburner/2.5.1" includes="jackson-module-afterburner-2.5.1.jar"/>
</jar>
</target>
</project>
`
For Example:
${project_path}/src/com/COMPANYNAME/PRODUCT/config.java
${project_path}/test/com/COMPANYNAME/PRODUCT/TestInitCode.java
${project_path}/target/classes/com/COMPANY/NAME/PRODUCT/config.class
${project_path}/target/classes/com/COMPANY/NAME/PRODUCT/TestInitCode.class
And I want the ${project_path}/test/ path to be completely excluded.
I am trying to execute a jar file StartupUtil.jar but it's giving an error of Couldnot find and load main class. I looked at other similar question and tried but couldnot figure out what is wrong.
My structure for created StartupUtil.jar is
->com.ihc.startup.util.StartupService
->META-INF/MANIFEST.MF
The content of MANIFEST is:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.2
Created-By: 1.7.0_79-b15 (Oracle Corporation)
Main-Class: com.ihc.startup.util.StartupService
Class-Path: C:\Users\tgupta12\workspace_new\IHC_Startup\lib\bson-3.0.1
.jar C:\Users\tgupta12\workspace_new\IHC_Startup\lib\mongodb-driver-3
.0.1.jar C:\Users\tgupta12\workspace_new\IHC_Startup\lib\mongodb-driv
er-core-3.0.1.jar C:\Users\tgupta12\workspace_new\IHC_Startup\classes
Here is my build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="Startup" default="build" basedir=".">
<property file="./build.properties" />
<path id="lib-classpath">
<fileset dir="${libApp.dir}">
<include name="*.jar"/>
</fileset>
<pathelement path="${bin.dir}"/>
</path>
<target name="build" description="Compile main source tree java files">
<echo message=" Build Startup Utility" />
<mkdir dir="${bin.dir}"/>
<echo message=" Compiling source files" />
<javac destdir="${bin.dir}" source="${versionJDK}" target="${versionTarget}" debug="true"
deprecation="false" optimize="false" failonerror="true" includeantruntime="false">
<src path="${src.dir}"/>
<classpath refid="lib-classpath"/>
</javac>
<echo message=" ...Compilation of source files OK" />
<echo message=" Generating JAR for Startup - StartupUtility.jar" />
<delete file="${out.dir}/${startup-util-name}" />
<!-- convert classpath to a flat list/string -->
<pathconvert property="lib.classpath" pathsep=" ">
<path refid="lib-classpath" />
<!--<flattenmapper />-->
</pathconvert>
<jar destfile = "${out.dir}/${startup-util-name}" basedir = "${bin.dir}" includes = "**/*">
<manifest >
<attribute name="Class-Path" value="${lib.classpath}" />
<attribute name="Main-Class" value="com.ihc.startup.util.StartupService"/>
</manifest>
</jar>
<echo message=" ...JAR Created for Startup" />
</target>
<target name="run" depends="build">
<java jar="${out.dir}/${startup-util-name}" fork="true"/>
</target>
Below is my build.properties file:
#Directories
build.dir=build
src.dir=src
libApp.dir=lib
out.dir=out
web.dir=WebContent/WEB-INF
bin.dir=classes
webcontent.dir=WebContent
#File Name
war-file-name=StartupService.war
startup-util-name=StartupUtil.jar
#Target Properties
versionJDK=1.7
versionTarget=1.7
When it tries to execute the target run it gives
Error: Could not find or load main class com.ihc.startup.util.StartupService
I strongly suspect that the problem is it can't find the dependencies, which means it can't properly load the main class. I've never seen absolute filenames given in a manifest before, nor am I convinced about how you're breaking the lines (although that may be valid). Given how unportable it is to use the absolute filenames, I strongly suggest you just use relative ones.
Change your manifest to just:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.2
Created-By: 1.7.0_79-b15 (Oracle Corporation)
Main-Class: com.ihc.startup.util.StartupService
Class-Path: bson-3.0.1.jar mongodb-driver-3.0.1.jar mongodb-driver-core-3.0.1.jar
Then put those jar files in the same directory as StartupUtil.jar.
How can we add additional parameters to manifest file using Maven to third party jars. After Java 7_25 version the Java web start requires codebase and permissions to be add in all downloading jar files. I want to insert them jar singing time.
Please let me know if you need any information. Thanks in advance.
i made a little ant script (this is an extract, in fact it also excludes some crypto file).
just set directory property value to a directory that contains jars to be updated and launch the target "give-permissions".
it should be easy to use with maven-ant:
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." name="project">
<taskdef resource="net/sf/antcontrib/antcontrib.properties" />
<property name="directory" value="WebContent/jnlpApplication" />
<target name="give-permissions">
<foreach target="_re-jar" param="currentFile" parallel="false">
<path>
<fileset dir="${directory}" casesensitive="yes">
<include name="**/*.jar" />
</fileset>
</path>
</foreach>
<move todir="${directory}" overwrite="true">
<fileset dir="${directory}.tmp" casesensitive="yes">
<include name="**/*.jar" />
</fileset>
</move>
<delete dir="${directory}.tmp" />
</target>
<target name="_re-jar">
<basename property="filename" file="${currentFile}" />
<jar destfile="${directory}.tmp/${filename}">
<zipfileset src="${currentFile}">
<exclude name="META-INF/**.RSA" />
<exclude name="META-INF/**.SF" />
</zipfileset>
<manifest>
<attribute name="Permissions" value="all-permissions" />
<attribute name="Codebase" value="*" />
<attribute name="Application-Name" value="jnlpApplicationName" />
</manifest>
</jar>
</target>
</project>
I have an Ant build.xml file that works just fine on the command line: it compiles, builds the JAR, and I am able to execute the main method from the JAR just fine. The build.xml file references several thirdparty libraries that are scattered here and there. When building the JAR, the script doesn't include all the thirdparty libraries into the JAR itself. Instead, it puts their path into the JAR's manifest. This helps to keep my JAR slim and tidy.
I'd like to be able to edit and debug my project in Eclipse, but I can't find an easy way to do so. I can have my project use the Ant file to build the project, and that seems to work. However, Eclipse is having trouble finding the thirdparty libaries, and thus Eclipse is having two problems:
it shows (in the text editor) lots of compile errors, because
lots of classes are undefined, and
it can't execute the JAR.
I can solve both of the above problems by specifying by hand, in two difference places (i.e., the build path via Properties->Java Build Path->Libraries, and the execution classpath via Run Configurations->Classpath), all the third party libraries. But it seems like I shouldn't have to do this manually, since all the third party libraries are already listed in my JAR's manifest. What am I doing wrong?
Here's my build.xml file:
<!-- Set global properties for this build -->
<property name="src" location="./src" />
<property name="build" location="./build"/>
<property name="dist" location="./dist"/>
<property name="logs" location="./logs"/>
<property name="docs" location="./docs"/>
<property name="jar" location="${dist}/dynamic_analyzer.jar"/>
<property name="lib" location="../../thirdparty/lib"/>
<property name="hive-util" location="../../hive-utils/dist"/>
<property name="hpdb" location="../../hive-db/hpdb/dist"/>
<property name="static" location="../../hive-backend/static_analyzer/dist"/>
<property name="mainclass" value="com.datawarellc.main.DynamicMain"/>
<path id="dep.runtime">
<fileset dir="${lib}" includes="**/*.jar"/>
<fileset dir="${hive-util}" includes="**/*.jar"/>
<fileset dir="${hpdb}" includes="**/*.jar"/>
<fileset dir="${static}" includes="**/*.jar"/>
</path>
<target name="clean">
<delete dir="${build}"/>
<delete dir="${dist}"/>
<delete dir="${docs}"/>
<delete dir="${logs}"/>
</target>
<target name="init">
<tstamp/>
<mkdir dir="${build}"/>
<mkdir dir="${dist}"/>
<mkdir dir="${logs}"/>
</target>
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}" debug="on" includeantruntime="false">
<classpath refid="dep.runtime" />
</javac>
<!-- Debug output of classpath -->
<property name="myclasspath" refid="dep.runtime"/>
<echo message="Classpath = ${myclasspath}"/>
</target>
<target name="jar" depends="compile">
<!-- Put the classpath in the manifest -->
<manifestclasspath property="manifest_cp" jarfile="${jar}" maxParentLevels="10">
<classpath refid="dep.runtime" />
</manifestclasspath>
<jar jarfile="${jar}" basedir="${build}">
<manifest>
<attribute name="Main-Class" value="${mainclass}"/>
<attribute name="Class-Path" value="${manifest_cp}"/>
</manifest>
<zipfileset dir="${src}" includes="**/*.xml" />
</jar>
</target>
You can see that I have third-party libraries in several directories (${lib}, ${hive-util}, ${hpdb}, and ${static}). I use these to create a path called dep.runtime. I then include dep.runtime in the manifest when building my jar. How can I get Eclipse to use the same dep.runtime for the build path and the classpath when executing?
An alternative to perl is to use an embedded groovy task:
<project name="demo" default="eclipse-files">
<property name="src.dir" location="src"/>
<property name="classes.dir" location="build/classes"/>
<path id="dep.runtime">
<fileset dir="${lib}" includes="**/*.jar"/>
<fileset dir="${hive-util}" includes="**/*.jar"/>
<fileset dir="${hpdb}" includes="**/*.jar"/>
<fileset dir="${static}" includes="**/*.jar"/>
</path>
<target name="bootstrap">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/groovy-all.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.1.4/groovy-all-2.1.4.jar"/>
</target>
<target name="eclipse-files">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<groovy>
import groovy.xml.MarkupBuilder
project.log "Creating .classpath"
new File(".classpath").withWriter { writer ->
def xml = new MarkupBuilder(writer)
xml.classpath() {
classpathentry(kind:"src", path:properties["src.dir"])
classpathentry(kind:"output", path:properties["classes.dir"])
classpathentry(kind:"con", path:"org.eclipse.jdt.launching.JRE_CONTAINER")
project.references."dep.runtime".each {
classpathentry(kind:"lib", path:it)
}
}
}
</groovy>
</target>
<target name="clean">
<delete file=".classpath"/>
</target>
</project>
Notes:
The bootstrap target will download the 3rd party groovy jar (No dependency on perl)
Groovy can access the "dep.runtime" ANT path directly and iterate over its contents
Groovy has excellent support for writing XML files.
The following answer is similar and additionally generates the Eclipse .project file.
Using Apache Ivy with netbeans
I came up with the following workaround, inspired by the link provided by #leeand00.
First, I wrote a simple Perl script (called genClasspath.pl) that generates the .classpath file that Eclipse uses.
#!/usr/bin/perl
use strict;
if (#ARGV != 2) {
print STDERR "Usage: $0 OUTFILE CLASSPATHSTRING\n";
print STDERR "e.g., $0 .classpath path1:path2:path3\n";
exit 1;
}
my $OUTFILE = $ARGV[0];
my $CLASSPATHSTRING = $ARGV[1];
open my $out_fh, '>', $OUTFILE or die "Couldn't open output file: $!";
print $out_fh q{<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="build"/>
};
my #libs = split(":", $CLASSPATHSTRING);
foreach my $thisLib (#libs){
print $out_fh " <classpathentry kind=\"lib\" path=\"$thisLib\"/>\n";
}
print $out_fh "</classpath>\n";
Then, I have my build.xml file call this script with the content of dep.runtime:
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}" debug="on" includeantruntime="false">
<classpath refid="dep.runtime" />
</javac>
<property name="myclasspath" refid="dep.runtime"/>
<exec dir="." executable="../../scripts/genClasspath.pl" os="Linux">
<arg value=".classpath"/>
<arg value="${myclasspath}"/>
</exec>
</target>
The only catch is that I need to run Ant on the command line at least once before I open the project in Eclipse. But when I do, Eclipse is able to compile and execute my project just fine, since the classpath is exactly the same as Ant's.