0

I am not that experienced with ivy and not sure how to solve this problem, which I probably caused myself by not understanding ivy.

so I have this in my ivysettings.xml to use a local filesystem repo

<ivysettings>
   <settings defaultResolver="central" />
   <resolvers>
      <ibiblio name="central" m2compatible="true"/>
      <filesystem name='local'>
        <artifact pattern='/home/tester/JAVA/tester-libs/'/>
      </filesystem>
   </resolvers>
   <modules>
      <module organisation="myorg" resolver="local"/>
   </modules>
</ivysettings>

JarL.java exsists in /home/tester/JAVA/tester-libs/

my dependencies are set in ivy.xml as

<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="1.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:noNamespaceSchemaLocation="http://www.jayasoft.org/misc/ivy/samples/ivy.xsd"
>
    <info organisation="org.naps" module="naps"/>
    <dependencies>
        <dependency org="commons-configuration" name="commons-configuration" rev="1.10"/>
        <dependency org="myorg" name="Jarl" rev="NA" changing="true"/>
    </dependencies>
</ivy-module>

which resolves the dependency but where all the other jars like commons-configuration are placed in lib/ during the build, my jar is placed in lib/JarL sub-directory.

I want JarL to be placed in lib/ like the other dependencies and have no idea what to do. I hacked these scripts together from other answers I found on the net.

Ivy is just too in-depth for me. I not want to take months out of my life to learn yet another tool. I just want easy lazy development where I concentrate on the problem at hand not the dev tools.

UPDATE:

For the moment I have had to add the following 2 lines to the packing step in build.xml to get around this problem but it is a silly fix.

<move file="lib/JarL-NA.jar/JarL.jar" todir="lib"/>
<delete dir="lib/JarL-NA.jar"/>

UPDATE: added build.xml as per Mark's request

<?xml version="1.0" encoding="UTF-8"?><!-- You may freely edit this file. See commented blocks below for --><!-- some examples of how to customize the build. --><!-- (If you delete it and reopen the project it will be recreated.) --><!-- By default, only the Clean and Build commands use this build script. --><project name="Naps" default="default" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant">
    <description>Builds, tests, and runs the project Naps.</description>
    <import file="nbproject/build-impl.xml"/>
    <!--

    There exist several targets which are by default empty and which can be 
    used for execution of your tasks. These targets are usually executed 
    before and after some main targets. Those of them relevant for JavaFX project are: 

      -pre-init:                 called before initialization of project properties
      -post-init:                called after initialization of project properties
      -pre-compile:              called before javac compilation
      -post-compile:             called after javac compilation
      -pre-compile-test:         called before javac compilation of JUnit tests
      -post-compile-test:        called after javac compilation of JUnit tests
      -pre-jfx-jar:              called before FX SDK specific <fx:jar> task
      -post-jfx-jar:             called after FX SDK specific <fx:jar> task
      -pre-jfx-deploy:           called before FX SDK specific <fx:deploy> task
      -post-jfx-deploy:          called after FX SDK specific <fx:deploy> task
      -pre-jfx-native:           called just after -pre-jfx-deploy if <fx:deploy> runs in native packaging mode
      -post-jfx-native:          called just after -post-jfx-deploy if <fx:deploy> runs in native packaging mode
      -post-clean:               called after cleaning build products

    (Targets beginning with '-' are not intended to be called on their own.)

    Example of inserting a HTML postprocessor after javaFX SDK deployment:

        <target name="-post-jfx-deploy">
            <basename property="jfx.deployment.base" file="${jfx.deployment.jar}" suffix=".jar"/>
            <property name="jfx.deployment.html" location="${jfx.deployment.dir}${file.separator}${jfx.deployment.base}.html"/>
            <custompostprocess>
                <fileset dir="${jfx.deployment.html}"/>
            </custompostprocess>
        </target>

    Example of calling an Ant task from JavaFX SDK. Note that access to JavaFX SDK Ant tasks must be
    initialized; to ensure this is done add the dependence on -check-jfx-sdk-version target:

        <target name="-post-jfx-jar" depends="-check-jfx-sdk-version">
            <echo message="Calling jar task from JavaFX SDK"/>
            <fx:jar ...>
                ...
            </fx:jar>
        </target>

    For more details about JavaFX SDK Ant tasks go to
    http://docs.oracle.com/javafx/2/deployment/jfxpub-deployment.htm

    For list of available properties check the files
    nbproject/build-impl.xml and nbproject/jfx-impl.xml.

    -->
    <target name="-check-for-ivy">
        <available property="have.ivy" resource="fr/jayasoft/ivy/ant/antlib.xml"/>
    </target>
    <target name="-ivy-define" depends="-check-for-ivy" unless="have.ivy">
        <taskdef resource="fr/jayasoft/ivy/ant/antlib.xml" uri="antlib:fr.jayasoft.ivy.ant">
            <classpath>
                <fileset dir="${ivy.home}">
                    <include name="ivy*.jar"/>
                    <include name="lib/*.jar"/>
                </fileset>
            </classpath>
        </taskdef>
    </target>
    <target name="-ivy-retrieve" depends="-ivy-define" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
        <ivy:resolve/> <!-- Tell Ivy to resolve dependencies -->
        <ivy:retrieve/> <!-- Load dependencies to the project -->
        <pathconvert property="ivy.classpath.computed" dirsep="/" pathsep=":">
            <path>
                <fileset dir="lib" includes="*.jar"/>
            </path>
            <map from="${basedir}${file.separator}" to=""/>
        </pathconvert>
        <propertyfile file="nbproject/project.properties">
            <entry operation="=" key="ivy.classpath" value="${ivy.classpath.computed}"/>
        </propertyfile>
    </target>
    <target name="-pre-compile" depends="-ivy-retrieve"/>
    <target name="-pre-compile-single" depends="-ivy-retrieve"/>
    <target name="-post-clean">
        <delete dir="lib"/>
    </target>

    <!-- fix ivy task -->
    <target name="-pre-jfx-jar">
        <move file="lib/JarL-NA.jar/JarL.jar" todir="lib"/>
        <delete dir="lib/JarL-NA.jar"/>
    </target>
</project>

and this is the nb properties file it loads

#Thu, 02 Jul 2015 05:24:03 +0100
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.processors.list=
annotation.processing.run.all.processors=true
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.splash=
application.title=Naps
application.vendor=Tester
auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
compile.on.save=true
compile.on.save.unsupported.javafx=true
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=${run.classpath}
debug.test.classpath=${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/Naps.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
includes=**
# Non-JavaFX jar file creation is deactivated in JavaFX 2.0+ projects
jar.archive.disabled=true
jar.compress=false
#
# Tester - replaced classpath with ivy
javac.classpath=${ivy.classpath}\:${javafx.classpath.extension}
# javac.classpath=\
#    ${javafx.classpath.extension}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.processorpath=${javac.classpath}
javac.source=1.8
javac.target=1.8
javac.test.classpath=${javac.classpath}\:${build.classes.dir}
javac.test.processorpath=${javac.test.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
javafx.application.implementation.version=1.0
javafx.binarycss=false
javafx.classpath.extension=${java.home}/lib/javaws.jar\:${java.home}/lib/deploy.jar\:${java.home}/lib/plugin.jar
javafx.deploy.adddesktopshortcut=false
javafx.deploy.addstartmenushortcut=false
javafx.deploy.allowoffline=true
# If true, application update mode is set to 'background', if false, update mode is set to 'eager'
javafx.deploy.backgroundupdate=false
javafx.deploy.disable.proxy=false
javafx.deploy.embedJNLP=true
javafx.deploy.icon=
javafx.deploy.icon.native=
javafx.deploy.includeDT=true
javafx.deploy.installpermanently=false
javafx.deploy.permissionselevated=false
javafx.deploy.splash=
# Set true to prevent creation of temporary copy of deployment artifacts before each run (disables concurrent runs)
javafx.disable.concurrent.runs=false
# Set true to enable multiple concurrent runs of the same WebStart or Run-in-Browser project
javafx.enable.concurrent.external.runs=false
# This is a JavaFX project
javafx.enabled=true
javafx.fallback.class=com.javafx.main.NoJavaFXFallback
# Main class for JavaFX
javafx.main.class=naps.Main
javafx.preloader.class=
# This project does not use Preloader
javafx.preloader.enabled=false
javafx.preloader.jar.filename=
javafx.preloader.jar.path=
javafx.preloader.project.path=
javafx.preloader.type=none
# Set true for GlassFish only. Rebases manifest classpaths of JARs in lib dir. Not usable with signed JARs.
javafx.rebase.libs=false
javafx.run.height=600
javafx.run.width=800
javafx.signing.blob=false
javafx.signing.enabled=false
javafx.signing.type=notsigned
# Pre-JavaFX 2.0 WebStart is deactivated in JavaFX 2.0+ projects
jnlp.enabled=false
# Main class for Java launcher
main.class=com.javafx.main.Main
# For improved security specify narrower Codebase manifest attribute to prevent RIAs from being repurposed
manifest.custom.codebase=*
# Specify Permissions manifest attribute to override default (choices: sandbox, all-permissions)
manifest.custom.permissions=
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
native.bundling.enabled=false
platform.active=default_platform
run.classpath=${dist.jar}\:${javac.classpath}\:${build.classes.dir}
run.test.classpath=${javac.test.classpath}\:${build.test.classes.dir}
source.encoding=UTF-8
src.dir=src
test.src.dir=test

ivy.classpath=lib/commons-beanutils-1.8.3.jar\:lib/commons-codec-1.6.jar\:lib/commons-collections-3.2.1.jar\:lib/commons-configuration-1.10-javadoc.jar\:lib/commons-configuration-1.10-sources.jar\:lib/commons-configuration-1.10.jar\:lib/commons-digester-1.8.1.jar\:lib/commons-jexl-2.1.1.jar\:lib/commons-jxpath-1.3.jar\:lib/commons-lang-2.6.jar\:lib/commons-logging-1.1.1.jar\:lib/commons-vfs2-2.0.jar\:lib/log4j-1.2.8.jar\:lib/maven-scm-api-1.4.jar\:lib/maven-scm-provider-svn-commons-1.4.jar\:lib/maven-scm-provider-svnexe-1.4.jar\:lib/plexus-utils-1.5.6.jar\:lib/regexp-1.3.jar\:lib/servlet-api-2.4.jar\:lib/xml-apis-1.0.b2.jar\:lib/xml-resolver-1.2.jar

UPDATE: Here is build.xml file changed to use an ivy retrieve pattern as mentioned by Mark Hunter

<?xml version="1.0" encoding="UTF-8"?><!-- You may freely edit this file. See commented blocks below for --><!-- some examples of how to customize the build. --><!-- (If you delete it and reopen the project it will be recreated.) --><!-- By default, only the Clean and Build commands use this build script. --><project name="Naps" default="default" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant">
    <description>Builds, tests, and runs the project Naps.</description>
    <import file="nbproject/build-impl.xml"/>
    <property name="one-jar.dist.dir" value="/home/tester/JAVA/one-jar-ant"/>
    <import file="${one-jar.dist.dir}/one-jar-ant-task.xml" optional="true"/>

    <target name="-check-for-ivy">
        <available property="have.ivy" resource="fr/jayasoft/ivy/ant/antlib.xml"/>
    </target>
    <target name="-ivy-define" depends="-check-for-ivy" unless="have.ivy">
        <taskdef resource="fr/jayasoft/ivy/ant/antlib.xml" uri="antlib:fr.jayasoft.ivy.ant">
            <classpath>
                <fileset dir="${ivy.home}">
                    <include name="ivy*.jar"/>
                    <include name="lib/*.jar"/>
                </fileset>
            </classpath>
        </taskdef>
    </target>
    <target name="-ivy-retrieve" depends="-ivy-define" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
        <ivy:resolve/> <!-- Tell Ivy to resolve dependencies -->
        <ivy:retrieve conf="napsjar" pattern="lib/[artifact].[ext]"/>
        <pathconvert property="ivy.classpath.computed" dirsep="/" pathsep=":">
            <path>
                <fileset dir="lib" includes="*.jar"/>
            </path>
            <map from="${basedir}${file.separator}" to=""/>
        </pathconvert>
        <propertyfile file="nbproject/project.properties">
            <entry operation="=" key="ivy.classpath" value="${ivy.classpath.computed}"/>
        </propertyfile>
    </target>
    <target name="-pre-compile" depends="-ivy-retrieve"/>
    <target name="-pre-compile-single" depends="-ivy-retrieve"/>
    <target name="-post-clean">
        <delete dir="lib"/>
    </target>

    <!-- fix ivy task -->
    <target name="-pre-jfx-jar">
        <move file="lib/JarL-NA.jar/JarL.jar" todir="lib"/>
        <delete dir="lib/JarL-NA.jar"/>
    </target>

    <!-- one-jar task -->
    <target name="-post-jfx-jar">
        <one-jar destfile="naps-one-jar.jar">
            <manifest>
                <attribute name="One-Jar-Main-Class" value="jarl.Main"/>
            </manifest>
            <main>
                <fileset dir="/home/tester/WORKSPACE/NetBeans/Naps/build/classes"/>
            </main>
            <lib>
                <fileset dir="/home/tester/WORKSPACE/NetBeans/Naps/lib"/>
            </lib>
        </one-jar>
    </target>    
</project>

here's ivy.xml using configurations, htough there is only so not sure why that should change anything

<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="1.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:noNamespaceSchemaLocation="http://www.jayasoft.org/misc/ivy/samples/ivy.xsd"
>
    <info organisation="org.naps" module="naps"/>
    <configurations>
        <conf name="napsjar" description="Jars used by application"/>
    </configurations>
    <dependencies>
        <dependency org="commons-configuration" name="commons-configuration" rev="1.10" conf="napsjar->default"/>
        <dependency org="NA"  name="JarL" rev="NA" conf="napsjar->default"/>
    </dependencies>
</ivy-module>

These changes have resulted in lib/JarL-NA.jar/JarL-NA.jar becoming lib/JarL.jar/JarL.jar, which is still in a sub-directory of lib and now prevents my simple rename step form working.

The rest of the dependencies are in lib as expected and as they were before.

Addtionally, these changes have now preventd nb from resolving commons-configuration so the source can no longer import the class.

Tuxxy_Thang
  • 179
  • 12
  • How are you running ivy? I run mine from ANT and that determines where the libraries are placed. – Goose Jul 01 '15 at 14:14
  • It is run from within netbeans – Tuxxy_Thang Jul 01 '15 at 14:19
  • Example: http://stackoverflow.com/questions/25505746/how-to-fix-configuration-not-found-in-guava-error/25512225#25512225 – Mark O'Connor Jul 01 '15 at 17:40
  • @MarkO'Connor I based my setup on that thread and it does not work. The path in it has to be adjusted for my project but after that it just builds the jar with the JarL file in a seperate sub-directory. – Tuxxy_Thang Jul 02 '15 at 03:53
  • I don't understand. Your update implies there is a problem in the way you are calling the ivy retrieve task, which has a pattern attribute that enables you control where ivy places resolved file. I would need to see your build file. See: http://stackoverflow.com/questions/4071009/split-retrieved-artifacts-in-two-separate-lib-directories/4092120#4092120 – Mark O'Connor Jul 02 '15 at 06:51
  • That I would be calling any ivy task incorrectly would not surprise me in the least. I copied/hacked my configuration from sparse information in a thread asking/solving the add ivy to nb question. I have uploaded build.xml and the referenced nb properties file as it seems to use some settings from in there. – Tuxxy_Thang Jul 02 '15 at 08:39
  • @MarkO'Connor btw, I had previously seen the link you posted in your comment and that did not work. However, I have looked at it again after your comment and now think I can see that the problem stems from the ivy-retrieve task I have coded with no pattern. I had seen use of the pattern in other threads but until you made your comment, I never understood that it is an output pattern, not input, so I wil have a go at solving this again. Manually creating build files has always been a pita I can do without, it is the 1 thing I hated about my c++ career. So I hacked this from another script. – Tuxxy_Thang Jul 02 '15 at 08:59
  • @MarkO'Connor I just made changes to use ivy configurations and retrieval patterns but it just seems to have made things worse. – Tuxxy_Thang Jul 02 '15 at 09:21

1 Answers1

3

The following project is an example of how to setup and use ivy tasks. The build file you're using looks like it was generated and follows some older usage patterns.

Hope it helps.

Example

This project has been customized to use a "local-libs" directory as a file repository. This caters for scenarios where some libs are shipped alongside the source because they're not available from an external repository like Maven Central.

├── build.xml
├── ivysettings.xml
├── ivy.xml
├── local-libs
│   └── JarL-1.0.jar
└── target
    ├── dist
    │   └── lib
    │       ├── commons-configuration-1.10.jar
    │       ├── commons-lang-2.6.jar
    │       ├── commons-logging-1.1.1.jar
    │       └── JarL-1.0.jar
    └── ivy-reports
        ├── ivy-report.css
        └── org.naps-naps-napsjar.html

After running the build two directories are created under the "target" directory:

  1. "dist/lib": Containing the files managed by ivy. Check how the resolve task works
  2. "ivy-reports": HTML report telling you how ivy determined the dependencies

It should be noted I also included an example of how to create a property containing a list of the classpath managed by ivy.

build.xml

Pay attention to the namespace at the top if the build file. Ivy no longer needs an explicit taskdef. Also include a target that installs ivy if it's not present on the build server. Finally note how the ivy "resolve", "report", "cachepath" and "retrieve" tasks are called:

<project name="demo" default="build" xmlns:ivy="antlib:org.apache.ivy.ant">

    <!--
    ================
    Build properties
    ================
    -->
    <property name="src.dir"          location="src/main/java"/>
    <property name="resources.dir"    location="src/main/resources"/>
    <property name="test.src.dir"     location="src/test/java"/>
    <property name="build.dir"        location="target"/>
    <property name="dist.dir"         location="${build.dir}/dist"/>

    <property name="jar.main.class" value="jarl.Main"/>
    <property name="jar.file"       value="${dist.dir}/${ant.project.name}.jar"/>

    <available classname="org.apache.ivy.Main" property="ivy.installed"/> 

    <!--
    ===========
    Build setup
    ===========
    -->
    <target name="install-ivy" description="Install ivy" unless="ivy.installed">
        <mkdir dir="${user.home}/.ant/lib"/>
        <get dest="${user.home}/.ant/lib/ivy.jar" src="http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.4.0/ivy-2.4.0.jar"/>
        <fail message="Ivy has been installed. Run the build again"/>
    </target>

    <target name="resolve" depends="install-ivy" description="Use ivy to resolve classpaths">
        <ivy:resolve/>

        <ivy:report todir='${build.dir}/ivy-reports' graph='false' xml='false'/>

        <ivy:cachepath pathid="naps.path" conf="napsjar"/>
    </target>

    <!--
    =====================
    Build and run targets
    =====================
    -->

    <target name="build" depends="resolve" description="Do stuff">

        <!-- Populate a lib directory with the ivy resolved files -->
        <ivy:retrieve pattern="${dist.dir}/lib/[artifact]-[revision](-[classifier]).[ext]" conf="napsjar"/>

        <!-- Print the classpath managed by ivy -->
        <pathconvert property="naps.path.prop" refid="naps.path"/>
        <echo message="Ivy managed classpath: ${naps.path.prop}"/>
    </target>


    <!--
    =============
    Clean targets
    =============
    -->
    <target name="clean" description="Cleanup build files">
        <delete dir="${build.dir}"/>
    </target>

    <target name="clean-all" depends="clean" description="Additionally purge ivy cache">
        <ivy:cleancache/>
    </target>

</project>

ivy.xml

Note how local files are referenced using the special organisation "NA"

<ivy-module version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.jayasoft.org/misc/ivy/samples/ivy.xsd" >
    <info organisation="org.naps" module="naps"/>
    <configurations>
        <conf name="napsjar" description="Jars used by application"/>
    </configurations>
    <dependencies>
        <dependency org="commons-configuration" name="commons-configuration" rev="1.10" conf="napsjar->default"/>
        <dependency org="NA" name="JarL" rev="1.0" conf="napsjar->default"/>
    </dependencies>
</ivy-module>

ivysettings.xml

The "modules" section tells ivy to resolve "NA" organisation artifacts using the file system resolver. The artifact pattern tells ivy how to resolve local files. Always a good idea to include a version number.

<ivysettings>
   <settings defaultResolver="central" />
   <resolvers>
      <ibiblio name="central" m2compatible="true"/>
      <filesystem name='local'>
        <artifact pattern='${ivy.settings.dir}/local-libs/[artifact]-[revision].[ext]'/>
      </filesystem>
   </resolvers>
   <modules>
      <module organisation="NA" resolver="local"/>
   </modules>
</ivysettings>
Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
  • Wow Mark, thanks very much. Looking at your code, I can see where I went wrong. Seems I hacked from 2 different incomplete examples. I can confirm your setup works fine outside netbeans but netbeans does not want to play. Had to change ant path to within the netbeans ide directory to solve the first problem but the 2nd is beyond me, deep inside the netbeans ant scripts. I've finished this project now so no longer care but thank you very much for explaining ivy to me. I now feel confident I can use ant+ivy at least from the cli. Looks so much easier without the netbeans ant scripts in the way. – Tuxxy_Thang Jul 04 '15 at 07:03
  • @Tuxxy_Thang I haven't used netbeans in a long time. At that time I liked the fact that it used ANT to build the project (via an import common build logic) as opposed to Eclipse's approach of internalizing how the java code was built. But..... experience has taught me that "common" build logic needs to be carefully applied. – Mark O'Connor Jul 04 '15 at 08:03
  • I love a lot of things about both nb and eclipse but mostly use eclipse now. This was a client's project already started in nb which I could not port cleanly in to eclipse due some weirdness so I had to struggle back in nb. I wish they would document their internal build scripts better but it is what it is. I tracked the problem down to their script adding the target jar to the lib path you created and then barfed cause they could not copy a non existent file. I lost it at that point. Thanks very much though, I now feel educated :D – Tuxxy_Thang Jul 04 '15 at 08:41