You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ivy-user@ant.apache.org by zharvey <za...@gmail.com> on 2011/09/15 15:07:05 UTC

ivy:publish build error

I'm trying to get a project up and running using Ivy for the first time ever.
I'm working on ivy:publish and getting an IllegalStateException stating:

ivy file not found in cache for myOrg#myModule;1.0: please resolve
dependencies before delivering
(C:\Users\MyUser\.ivy2\cache\resolved-myOrg-myModule-1.0.xml)

Now I am running publish after I have ran configure, resolve and retrieve,
and I have verified that those tasks, combined with my normal build process,
are producing my JAR (MyModule-1.0.jar) under the dist directory in my
project.

I suspect that somehow, perhaps, either my project directory, or possibly
even my cache, is not organized in such a way that Ivy recognizes where
MyModule-1.0.jar is.

Essentially, I want that JAR to get published to a "pubRepo" repository that
I define in my settings file. I'm just so overwhelmed by so many variables,
I don't even know where to start the debugging process.

Does anybody have any ideas as to what is happening here?
-- 
View this message in context: http://old.nabble.com/ivy%3Apublish-build-error-tp32471426p32471426.html
Sent from the ivy-user mailing list archive at Nabble.com.


Re: ivy:publish build error

Posted by Kirby Files <kf...@masergy.com>.
zharvey wrote on 09/15/2011 10:56 AM:
> (c) It, theoretically, would be possible to script my Apache server to
> accept the PUT from Ivy and write these files to my ivyrepo. (Yes, I am
> aware of the security concerns that will arise from this, and would have to
> take measure into my own hands on that account).

Well, I'm not sure what Ivy actually has or has not attempted in your 
case (wireshark could tell you for sure).

I wouldn't use bare PUTs to publish artifacts myself to a URL 
resolver, even if Ivy does allow it.

I would like some security and authentication on writes to my 
repository. It would be tricky to get Apache and Ivy to implement any 
decent security on bare puts. I suppose you could implement HTTP Basic 
Auth and encode the user/pass in the URL of the resolver, but that 
would be hackish and insecure indeed.

If you're going to use a remote resolver, I'd use one designed for 
writing with solid session authentication: Webdav is a good choice, as 
is SFTP.

A lot of folks just export the filesystem underlying the HTTP docroot 
via NFS or CIFS, and then use a filesystem resolver to publish. Then 
your filesystem permissions handle security.

Still others use the Ivy-SVN integration to publish to a subversion 
repo, and then use svnweb to access the repo.

All are valid choices; which is best for you will depend upon your 
environment, VCS, and toolchain.

Thanks,
---
Kirby Files
Software Architect
Masergy Communications
kfiles@masergy.com

Re: ivy:publish build error

Posted by zharvey <za...@gmail.com>.
Kirby,

I have a number of sub-questions spawning from your last (and very helpful!)
response; but only one of them concerns me immediately. I'll address the
others later.

I guess it makes sense that you can't write to a HTTP url. However, HTTP
does have the PUT method. And now that I've cleaned up my XML scripts (from
the examples & input you provided) I am now getting a completely different
error; one that jives with your statements in the last response:

IOException: PUT operation to URL
http://my-server.net/ivyrepo/artifacts/myOrg/MyModule-1.0.jar failed with
status code 405: Method Not Allowed.

According to W3C, HTTP 405s get thrown for a number of reasons, one of which
is "attempting to write to a read-only resource."

So this has me thinking: I'm using the URL (default) resolver to try and
publish my artifact, and Ivy is smart enough to translate that into an HTTP
PUT operation.

It turns out that the Apache httpd server (which is what I'm using for
"my-server.net") can be configured, albeit hackaliciously, to in fact accept
PUT commands.

My question to you and the Old Nabble community at large is this: which of
the following siutations (if any) are the case here:
(a) Ivy intrinsicly prohibits URL resolver to publish (write) artifacts,
regardless of web server settings at the URL; or
(b) There's no way get both the module descriptor and the artifact bundled
up inside the same ivy:publish execute since HTTP PUT only accepts 1 item;
or
(c) It, theoretically, would be possible to script my Apache server to
accept the PUT from Ivy and write these files to my ivyrepo. (Yes, I am
aware of the security concerns that will arise from this, and would have to
take measure into my own hands on that account).

Or, is there some other angle I'm not seeing? Based on the IOException I'm
reading in my console, it sounds like option (c) might be feasible. But you
seem to be very well-versed with Ivy, and from reading your last response,
it sounds like (a) or (b) could be the case.

I just don't want to launch down some crazy avenue and spend a 1/2 day
reconfigging my web server only to find out that (c) was never a possibility
in the first place.

I appreciate everything you've helped me with so far and am interested in
hearing what the community thinks.

Kirby Files wrote:
> 
> zharvey wrote on 09/15/2011 09:29 AM:
>>
>> Hi Kirby,
>>
>> Thanks for getting back to me so quickly.
>>
>> Here's my settings file (ivy-settings.xml):
>> ===============================
>> <ivysettings>
>> 	<properties file="ivy-settings.properties"/>
>>      <settings defaultResolver="defResolver"/>
>>      <latest-strategies>
>>      	<latest-lexico/>
>>      </latest-strategies>
>>      <resolvers>
>>          <chain name="defResolver" returnFirst="true">
>>           	<url name="jarServer">
>> 				<ivy
>> pattern="http://my-server.net/module_descriptors/[organisation]/[module]-[revision]-ivy.xml"/>
>> 				<artifact
>> pattern="http://my-server.net/artifacts/[organisation]/[artifact]-[revision].[ext]"/>
>>           	</url>
>>          </chain>
>>      </resolvers>
> 
> You only have url resolvers defined here. You cannot really publish to 
> those. You need to publish to a resolver you can write to: filesystem, 
> sftp, webdav via common-vfs, etc.
> 
>>      <modules>
>>      	<module organisation="myOrg" name="*" resolver="defResolver"/>
>>      </modules>
> 
> If you have a defaultResolver defined, as you do above, you don't need 
> to do explicit module mapping to a resolver.
> 
> 
>>      <publications defaultconf="publish">
>> 		<artifact name="MyModule" />
>> 	</publications>
> 
> You're going to publish your artifacts to a configuration named 
> publish, so any modules depending on MyModule will need to have a 
> confMapping of compile->publish. Is that what you want? I typically 
> publish artifacts to configurations based upon how they will be used 
> by the consuming project. So jars needed for running an app will be in 
> the "runtime" configuration, while jars only needed for building will 
> be published to the "compile" configuration, etc. I also defined 
> javadocs and sources configurations.
> 
> 
>> 	<!-- Ivy "publish" task; publish the distribution to SVN for downstream
>> projects -->
>> 	<target name="publish">
>> 		<ivy:publish organisation="myOrg" module="MyModule"
>> resolver="defResolver"
>> revision="1.0">
>> 			<artifacts pattern="dist/[artifact]-[revision].[ext]"/>
>> 		</ivy:publish>
>> 	</target>
>> </project>
> 
> So there's your problem. The publish target needs to depend on the 
> resolve target, which needs to depend on the settings target.
> 
> The settings task should only ever be run once during an ant build, so 
> I guard against executing twice (say resolve->settings and 
> deliver->settings are both executed in the same build):
> 
>      <target name="ivysettings" unless="ivysettings.completed">
>          <property name="ivysettings.completed" value="true" />
>          <ivy:settings id="ivy.instance"
>                        url="${ivy.settings.url}"
>          />
>      </target>
> 
> 
> You'll also want to publish to a resolver to which you can write. I 
> generally would not add the artifacts child element (use publications 
> in ivy.xml instead); use artifactspattern to define where to find the 
> jars specified in <publications>. Unless you have multiple modules per 
> buildfile, I wouldn't use the org or module attributes, either. You 
> should probably specify a pubrevision and status.
> 
> Here's an example from one of my projects:
> 
>      <target name="publish_only"
>              depends="resolve"
>              description="--&gt; publish this project in the prod ivy 
> repository">
>          <property name="revision" value="${version}" />
>          <ivy:publish 
> artifactspattern="${dist.dir}/[type]s/[artifact]-[revision].[ext]"
>                       resolver="masrep_sftp"
>                       pubrevision="${revision}"
>                       status="release"
>                       overwrite="false"
>                       update="true" />
>          <echo message="project ${ant.project.name} released with 
> version ${revision}" />
>      </target>
> 
> Also,
> Thanks,
> ---
> Kirby Files
> Software Architect
> Masergy Communications
> kfiles@masergy.com
> 
> 
> 

-- 
View this message in context: http://old.nabble.com/ivy%3Apublish-build-error-tp32471426p32472271.html
Sent from the ivy-user mailing list archive at Nabble.com.


Re: ivy:publish build error

Posted by Kirby Files <kf...@masergy.com>.
zharvey wrote on 09/15/2011 09:29 AM:
>
> Hi Kirby,
>
> Thanks for getting back to me so quickly.
>
> Here's my settings file (ivy-settings.xml):
> ===============================
> <ivysettings>
> 	<properties file="ivy-settings.properties"/>
>      <settings defaultResolver="defResolver"/>
>      <latest-strategies>
>      	<latest-lexico/>
>      </latest-strategies>
>      <resolvers>
>          <chain name="defResolver" returnFirst="true">
>           	<url name="jarServer">
> 				<ivy
> pattern="http://my-server.net/module_descriptors/[organisation]/[module]-[revision]-ivy.xml"/>
> 				<artifact
> pattern="http://my-server.net/artifacts/[organisation]/[artifact]-[revision].[ext]"/>
>           	</url>
>          </chain>
>      </resolvers>

You only have url resolvers defined here. You cannot really publish to 
those. You need to publish to a resolver you can write to: filesystem, 
sftp, webdav via common-vfs, etc.

>      <modules>
>      	<module organisation="myOrg" name="*" resolver="defResolver"/>
>      </modules>

If you have a defaultResolver defined, as you do above, you don't need 
to do explicit module mapping to a resolver.


>      <publications defaultconf="publish">
> 		<artifact name="MyModule" />
> 	</publications>

You're going to publish your artifacts to a configuration named 
publish, so any modules depending on MyModule will need to have a 
confMapping of compile->publish. Is that what you want? I typically 
publish artifacts to configurations based upon how they will be used 
by the consuming project. So jars needed for running an app will be in 
the "runtime" configuration, while jars only needed for building will 
be published to the "compile" configuration, etc. I also defined 
javadocs and sources configurations.


> 	<!-- Ivy "publish" task; publish the distribution to SVN for downstream
> projects -->
> 	<target name="publish">
> 		<ivy:publish organisation="myOrg" module="MyModule" resolver="defResolver"
> revision="1.0">
> 			<artifacts pattern="dist/[artifact]-[revision].[ext]"/>
> 		</ivy:publish>
> 	</target>
> </project>

So there's your problem. The publish target needs to depend on the 
resolve target, which needs to depend on the settings target.

The settings task should only ever be run once during an ant build, so 
I guard against executing twice (say resolve->settings and 
deliver->settings are both executed in the same build):

     <target name="ivysettings" unless="ivysettings.completed">
         <property name="ivysettings.completed" value="true" />
         <ivy:settings id="ivy.instance"
                       url="${ivy.settings.url}"
         />
     </target>


You'll also want to publish to a resolver to which you can write. I 
generally would not add the artifacts child element (use publications 
in ivy.xml instead); use artifactspattern to define where to find the 
jars specified in <publications>. Unless you have multiple modules per 
buildfile, I wouldn't use the org or module attributes, either. You 
should probably specify a pubrevision and status.

Here's an example from one of my projects:

     <target name="publish_only"
             depends="resolve"
             description="--&gt; publish this project in the prod ivy 
repository">
         <property name="revision" value="${version}" />
         <ivy:publish 
artifactspattern="${dist.dir}/[type]s/[artifact]-[revision].[ext]"
                      resolver="masrep_sftp"
                      pubrevision="${revision}"
                      status="release"
                      overwrite="false"
                      update="true" />
         <echo message="project ${ant.project.name} released with 
version ${revision}" />
     </target>

Also,
Thanks,
---
Kirby Files
Software Architect
Masergy Communications
kfiles@masergy.com


Re: ivy:publish build error

Posted by zharvey <za...@gmail.com>.
Hi Kirby,

Thanks for getting back to me so quickly.

Here's my settings file (ivy-settings.xml):
===============================
<ivysettings>  
	<properties file="ivy-settings.properties"/>
    <settings defaultResolver="defResolver"/>
    <latest-strategies>
    	<latest-lexico/>
    </latest-strategies>
    <resolvers>  
        <chain name="defResolver" returnFirst="true">
         	<url name="jarServer">
				<ivy
pattern="http://my-server.net/module_descriptors/[organisation]/[module]-[revision]-ivy.xml"/>
				<artifact
pattern="http://my-server.net/artifacts/[organisation]/[artifact]-[revision].[ext]"/>
         	</url>
        </chain>  
    </resolvers>  
    <modules>
    	<module organisation="myOrg" name="*" resolver="defResolver"/>
    </modules>
</ivysettings>

And my ivy file (ivy.xml):
==================
<?xml version="1.0" encoding="UTF-8"?>  
<ivy-module version="2.0"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
   
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">  
    <info organisation="myOrg" module="MyModule" />  
    <configurations>
        <conf name="compile" description="used for building" />  
        <conf name="publish" description="used for publishing" />  
    </configurations>  
    <publications defaultconf="publish">
		<artifact name="MyModule" />
	</publications>
    <dependencies>  
        <dependency org="apache" name="commons-cli" rev="1.2"
conf="compile->default"/> 
    </dependencies>
</ivy-module>

And the ivy portions of my buildscript (build.xml - way too long to put the
whole thing in here):
=======================================================================
<project name="LoaderServiceLoadTester" default="dist" basedir="."
	xmlns:ivy="antlib:org.apache.ivy.ant">
	<!-- Ivy task definitions --> 
	<taskdef name="ivy-configure" classname="org.apache.ivy.ant.IvyConfigure"/>
	<taskdef name="ivy-resolve" classname="org.apache.ivy.ant.IvyResolve"/>
	<taskdef name="ivy-retrieve" classname="org.apache.ivy.ant.IvyRetrieve"/>
	<taskdef name="ivy-cleancache"
classname="org.apache.ivy.ant.IvyCleanCache"/>
	<taskdef name="ivy-publish" classname="org.apache.ivy.ant.IvyPublish"/>
	
	<!-- Identify the Ivy settings file to use -->
	<ivy:settings
url="http://my-server.net/ivyrepo/settings/ivy-settings.xml"/>

	<!-- Ivy "resolve" task; resolve all project dependencies and cache them
--> 
	<target name="resolve">
		<ivy:configure host="http://my-server.net"
			realm="IvyTestProject"
			username="fizz"
			passwd="buzz"
			override="false"/>
		<ivy:resolve file="ivy.xml" conf="compile"/>
		<ivy:retrieve pattern="dist/[artifact]-[revision].[ext]" conf=compile"/>
	</target>
	
	<!-- Ivy "cleancache" task; to be used with caution. Flushes local cache
completely -->
	<target name="clean-ivy-cache">
		<ivy:cleancache/>
	</target>
		
	<!-- Ivy "publish" task; publish the distribution to SVN for downstream
projects --> 
	<target name="publish">
		<ivy:publish organisation="myOrg" module="MyModule" resolver="defResolver"
revision="1.0">
			<artifacts pattern="dist/[artifact]-[revision].[ext]"/>
		</ivy:publish>
	</target>
</project>


Hope this helps with a diagnosis...and thanks again for taking the time to
look at my problem!


Kirby Files wrote:
> 
> zharvey wrote on 09/15/2011 09:07 AM:
>>
>> I'm trying to get a project up and running using Ivy for the first time
>> ever.
>> I'm working on ivy:publish and getting an IllegalStateException stating:
>>
>> ivy file not found in cache for myOrg#myModule;1.0: please resolve
>> dependencies before delivering
>> (C:\Users\MyUser\.ivy2\cache\resolved-myOrg-myModule-1.0.xml)
> 
> It sounds like you aren't doing the resolve in the same ant run as the 
> publish, perhaps. Generally, a publish task should be preceded by an 
> ivy:settings and an ivy:resolve call.
> 
>> Essentially, I want that JAR to get published to a "pubRepo" repository
>> that
>> I define in my settings file. I'm just so overwhelmed by so many
>> variables,
>> I don't even know where to start the debugging process.
>>
>> Does anybody have any ideas as to what is happening here?
> 
> The best thing to do when you have specific troubleshooting questions 
> is to attach your ivy-settings.xml, ivy.xml, build.xml, and any logs.
> 
> Thanks,
> ---
> Kirby Files
> Software Architect
> Masergy Communications
> kfiles@masergy.com
> 
> 

-- 
View this message in context: http://old.nabble.com/ivy%3Apublish-build-error-tp32471426p32471596.html
Sent from the ivy-user mailing list archive at Nabble.com.


Re: ivy:publish build error

Posted by Kirby Files <kf...@masergy.com>.
zharvey wrote on 09/15/2011 09:07 AM:
>
> I'm trying to get a project up and running using Ivy for the first time ever.
> I'm working on ivy:publish and getting an IllegalStateException stating:
>
> ivy file not found in cache for myOrg#myModule;1.0: please resolve
> dependencies before delivering
> (C:\Users\MyUser\.ivy2\cache\resolved-myOrg-myModule-1.0.xml)

It sounds like you aren't doing the resolve in the same ant run as the 
publish, perhaps. Generally, a publish task should be preceded by an 
ivy:settings and an ivy:resolve call.

> Essentially, I want that JAR to get published to a "pubRepo" repository that
> I define in my settings file. I'm just so overwhelmed by so many variables,
> I don't even know where to start the debugging process.
>
> Does anybody have any ideas as to what is happening here?

The best thing to do when you have specific troubleshooting questions 
is to attach your ivy-settings.xml, ivy.xml, build.xml, and any logs.

Thanks,
---
Kirby Files
Software Architect
Masergy Communications
kfiles@masergy.com