You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@buildr.apache.org by Matteo Vaccari <va...@pobox.com> on 2011/08/01 16:58:13 UTC

Problems with dependent projects

Hi,

I'm new to Buildr; I'd really want to use it for my project, but I'm running
into a couple of problems with dependent projects, and I would be very
grateful if you could lend me a hand.

It boils down to this: if you have a simple setup like

define 'problematic', :version => '0.0' do
  define 'foo' do
    package :jar
  end

  define 'bar' do
    compile.with project('foo')
  end
end

where both projects are Java project.

Problem one: it will only work if project 'foo' is packaged as a jar.  Is
there a way to make it work when 'foo' is packaged as a war?  Because when
you package 'foo' as a war, the compile task for 'bar' fails.

Problem two: suppose project 'bar's test classes need to be compiled with
project 'foo's test classes.  I see in the wiki there's a suggested
workaround

define "A" do
  package(:jar)
end

define "B" do
  compile.with project("A")
  test.with project("A").test.compile.target  # <---- HERE
  package(:jar)
end

This works for the compile task, but it breaks the eclipse task.  It turns
out that the generated .classpath contains an entry like

  <classpathentry
path="/Users/matteo/work/problematic/foo/target/test/classes" kind="src"
excluding="**/.svn/|**/CVS/"/>

that does not work in Eclipse.

What can I do?

Matteo

Re: Problems with dependent projects

Posted by Matteo Vaccari <va...@pobox.com>.
On Tue, Aug 2, 2011 at 2:18 AM, Alex Boisvert <al...@gmail.com> wrote:
> On Mon, Aug 1, 2011 at 5:12 PM, Peter Donald <pe...@realityforge.org> wrote:
>
>> On Tue, Aug 2, 2011 at 10:07 AM, Peter Donald <peter@realityforge.org
>> >wrote:
>>
>> > In the Intellij IDE support we actually use the class paths if the
>> > dependency is part of a project. i.e. project('foo') will result
>> > in project('foo')._(:target, :main, :classes) added to the IDE project
>> files
>> > as will project('foo').package(:jar)
>> >
>> >
>> ... and thus I am suggesting that the same pattern could be followed in
>>  the
>> eclipse plugin.
>>
>
> Yes, this is what the eclipse task does already.
>
> There are two issues here,
>
> 1) compile.with project('foo') doesn't work as people expect when foo
> doesn't export a package(:jar)
>
> 2) eclipse task doesn't work with compile.with project('foo').compile.target
> and the likes.
>
> alex
>

I filed a bug for the Eclipse task
https://issues.apache.org/jira/browse/BUILDR-604

I also documented how I solved both problems in the wiki
https://cwiki.apache.org/confluence/display/BUILDR/How+to+depend+on+a+war-packaged+project

My buildr setup now works well.  Keep it up!

Matteo

Re: Problems with dependent projects

Posted by Alex Boisvert <al...@gmail.com>.
On Mon, Aug 1, 2011 at 5:12 PM, Peter Donald <pe...@realityforge.org> wrote:

> On Tue, Aug 2, 2011 at 10:07 AM, Peter Donald <peter@realityforge.org
> >wrote:
>
> > In the Intellij IDE support we actually use the class paths if the
> > dependency is part of a project. i.e. project('foo') will result
> > in project('foo')._(:target, :main, :classes) added to the IDE project
> files
> > as will project('foo').package(:jar)
> >
> >
> ... and thus I am suggesting that the same pattern could be followed in
>  the
> eclipse plugin.
>

Yes, this is what the eclipse task does already.

There are two issues here,

1) compile.with project('foo') doesn't work as people expect when foo
doesn't export a package(:jar)

2) eclipse task doesn't work with compile.with project('foo').compile.target
and the likes.

alex

Re: Problems with dependent projects

Posted by Peter Donald <pe...@realityforge.org>.
On Tue, Aug 2, 2011 at 10:07 AM, Peter Donald <pe...@realityforge.org>wrote:

> In the Intellij IDE support we actually use the class paths if the
> dependency is part of a project. i.e. project('foo') will result
> in project('foo')._(:target, :main, :classes) added to the IDE project files
> as will project('foo').package(:jar)
>
>
... and thus I am suggesting that the same pattern could be followed in  the
eclipse plugin.

-- 
Cheers,

Peter Donald

Re: Problems with dependent projects

Posted by Peter Donald <pe...@realityforge.org>.
On Tue, Aug 2, 2011 at 4:28 AM, Alex Boisvert <al...@gmail.com>wrote:

> Ignoring backward compatibility for a second, I'd be OK to changing
> compile.with such that any referenced project is mapped to both its
> compile.target and test.compile.target.  (And for consistency, we would use
> the same rule for test.with, run.with and similar functions.)   However, if
> you'd want to use foo's jar then you'd need to write compile.with
> project('foo').package(:jar) instead.     But I wouldn't want to get into
> rules that look like "if foo exports a jar, use it, otherwise use its
> compile.target, yaddy-yadda."  It's too much to require our users to
> remember these rules and they could easily get confused.
>

> I think this change would align us better which today's IDE defaults and
> people's initial expectations.  So my only restraint is that we would need
> to roll this out in a backward-compatibility-breaking major release.  It
> couldn't go in a minor release.
>

If at all possible I would prefer not to make this change. In quite a few
projects we post-process classes before they get into a jar or as they go
into a jar or ... And this would be made a bit more difficult under this new
model.

In the Intellij IDE support we actually use the class paths if the
dependency is part of a project. i.e. project('foo') will result
in project('foo')._(:target, :main, :classes) added to the IDE project files
as will project('foo').package(:jar)


-- 
Cheers,

Peter Donald

Re: Problems with dependent projects

Posted by Alex Boisvert <al...@gmail.com>.
On Mon, Aug 1, 2011 at 10:50 AM, Matteo Vaccari <va...@pobox.com> wrote:

> My feeling is that it should work like this:
>
> > define 'problematic' do
> >   define 'foo' do
> >     package :war
> >   end
> >
> >   define 'bar' do
> >     compile.with project('foo')
> >   end
> > end
>
> This works OK in eclipse, as it lets bar use both src and test from
> foo.  It fails in compilation though.  I would say that the problem is
> in the compile task.
>

I understand where you're coming from but we have to make sure the rules are
straight and simple;  I don't want this sort of thing to be magical
otherwise things quickly become unwieldy.

compile.with is currently defined as,

    # :call-seq:
    #   with(*artifacts) => self
    #
    # Adds files and artifacts as dependencies, and returns self.
    #
    # Calls #artifacts on the arguments, so you can pass artifact
specifications,
    # tasks, projects, etc. Use this rather than setting the dependencies
array directly.
    #
    # For example:
    #   compile.with('module1.jar', 'log4j:log4j:jar:1.0', project('foo'))
    def with(*specs)
      @dependencies |= Buildr.artifacts(specs.flatten).uniq
      self
    end

So when you reference project('foo') in compile.with, you get foo's
published artifacts -- basically today foo decides what gets exported.

Ignoring backward compatibility for a second, I'd be OK to changing
compile.with such that any referenced project is mapped to both its
compile.target and test.compile.target.  (And for consistency, we would use
the same rule for test.with, run.with and similar functions.)   However, if
you'd want to use foo's jar then you'd need to write compile.with
project('foo').package(:jar) instead.     But I wouldn't want to get into
rules that look like "if foo exports a jar, use it, otherwise use its
compile.target, yaddy-yadda."  It's too much to require our users to
remember these rules and they could easily get confused.

I think this change would align us better which today's IDE defaults and
people's initial expectations.  So my only restraint is that we would need
to roll this out in a backward-compatibility-breaking major release.  It
couldn't go in a minor release.

Thoughts from the peanut gallery?

alex

Re: Problems with dependent projects

Posted by Matteo Vaccari <va...@pobox.com>.
On Mon, Aug 1, 2011 at 7:45 PM, Alex Boisvert <al...@gmail.com> wrote:
> On Mon, Aug 1, 2011 at 9:30 AM, Matteo Vaccari <va...@pobox.com> wrote:
>
>> On Mon, Aug 1, 2011 at 4:58 PM, Matteo Vaccari <va...@pobox.com> wrote:
>> >
>> > Hi,
>> > I'm new to Buildr; I'd really want to use it for my project, but I'm
>> running into a couple of problems with dependent projects, and I would be
>> very grateful if you could lend me a hand.
>> > It boils down to this: if you have a simple setup like
>> > define 'problematic', :version => '0.0' do
>> >   define 'foo' do
>> >     package :jar
>> >   end
>> >
>> >   define 'bar' do
>> >     compile.with project('foo')
>> >   end
>> > end
>> > where both projects are Java project.
>> > Problem one: it will only work if project 'foo' is packaged as a jar.  Is
>> there a way to make it work when 'foo' is packaged as a war?  Because when
>> you package 'foo' as a war, the compile task for 'bar' fails.
>> > Problem two: suppose project 'bar's test classes need to be compiled with
>> project 'foo's test classes.  I see in the wiki there's a suggested
>> workaround
>> > define "A" do
>> >   package(:jar)
>> > end
>> > define "B" do
>> >   compile.with project("A")
>> >   test.with project("A").test.compile.target  # <---- HERE
>> >   package(:jar)
>> > end
>> > This works for the compile task, but it breaks the eclipse task.  It
>> turns out that the generated .classpath contains an entry like
>> >   <classpathentry
>> path="/Users/matteo/work/problematic/foo/target/test/classes" kind="src"
>> excluding="**/.svn/|**/CVS/"/>
>> > that does not work in Eclipse.
>> > What can I do?
>>
>> OK, I found a sort-of solution for both problems:
>>
>> define 'problematic' do
>>   define 'foo' do
>>     package :war
>>   end
>>
>>   define 'bar' do
>>     foo_src = project('foo').compile.target
>>     foo_test = project('foo').test.compile.target
>>     compile.with project('foo'), foo_src, foo_test
>>     eclipse.exclude_libs += [foo_src, foo_test]
>>   end
>> end
>>
>> The first entry in compile.with is used by the eclipse task, to set up
>> the correct dependency on 'foo'.  The other two are used by the
>> compile task.  The eclipse.exclude_libs fixes the incorrect entries in
>> .classpath.
>>
>
> I think that's the right way to do things... except for the eclipse
> exclusions -- those should be properly handled by the eclipse task.  Please
> file a bug.

My feeling is that it should work like this:

> define 'problematic' do
>   define 'foo' do
>     package :war
>   end
>
>   define 'bar' do
>     compile.with project('foo')
>   end
> end

This works OK in eclipse, as it lets bar use both src and test from
foo.  It fails in compilation though.  I would say that the problem is
in the compile task.

Matteo

Re: Problems with dependent projects

Posted by Alex Boisvert <al...@gmail.com>.
On Mon, Aug 1, 2011 at 9:30 AM, Matteo Vaccari <va...@pobox.com> wrote:

> On Mon, Aug 1, 2011 at 4:58 PM, Matteo Vaccari <va...@pobox.com> wrote:
> >
> > Hi,
> > I'm new to Buildr; I'd really want to use it for my project, but I'm
> running into a couple of problems with dependent projects, and I would be
> very grateful if you could lend me a hand.
> > It boils down to this: if you have a simple setup like
> > define 'problematic', :version => '0.0' do
> >   define 'foo' do
> >     package :jar
> >   end
> >
> >   define 'bar' do
> >     compile.with project('foo')
> >   end
> > end
> > where both projects are Java project.
> > Problem one: it will only work if project 'foo' is packaged as a jar.  Is
> there a way to make it work when 'foo' is packaged as a war?  Because when
> you package 'foo' as a war, the compile task for 'bar' fails.
> > Problem two: suppose project 'bar's test classes need to be compiled with
> project 'foo's test classes.  I see in the wiki there's a suggested
> workaround
> > define "A" do
> >   package(:jar)
> > end
> > define "B" do
> >   compile.with project("A")
> >   test.with project("A").test.compile.target  # <---- HERE
> >   package(:jar)
> > end
> > This works for the compile task, but it breaks the eclipse task.  It
> turns out that the generated .classpath contains an entry like
> >   <classpathentry
> path="/Users/matteo/work/problematic/foo/target/test/classes" kind="src"
> excluding="**/.svn/|**/CVS/"/>
> > that does not work in Eclipse.
> > What can I do?
>
> OK, I found a sort-of solution for both problems:
>
> define 'problematic' do
>   define 'foo' do
>     package :war
>   end
>
>   define 'bar' do
>     foo_src = project('foo').compile.target
>     foo_test = project('foo').test.compile.target
>     compile.with project('foo'), foo_src, foo_test
>     eclipse.exclude_libs += [foo_src, foo_test]
>   end
> end
>
> The first entry in compile.with is used by the eclipse task, to set up
> the correct dependency on 'foo'.  The other two are used by the
> compile task.  The eclipse.exclude_libs fixes the incorrect entries in
> .classpath.
>

I think that's the right way to do things... except for the eclipse
exclusions -- those should be properly handled by the eclipse task.  Please
file a bug.

alex

Re: Problems with dependent projects

Posted by Matteo Vaccari <va...@pobox.com>.
On Mon, Aug 1, 2011 at 4:58 PM, Matteo Vaccari <va...@pobox.com> wrote:
>
> Hi,
> I'm new to Buildr; I'd really want to use it for my project, but I'm running into a couple of problems with dependent projects, and I would be very grateful if you could lend me a hand.
> It boils down to this: if you have a simple setup like
> define 'problematic', :version => '0.0' do
>   define 'foo' do
>     package :jar
>   end
>
>   define 'bar' do
>     compile.with project('foo')
>   end
> end
> where both projects are Java project.
> Problem one: it will only work if project 'foo' is packaged as a jar.  Is there a way to make it work when 'foo' is packaged as a war?  Because when you package 'foo' as a war, the compile task for 'bar' fails.
> Problem two: suppose project 'bar's test classes need to be compiled with project 'foo's test classes.  I see in the wiki there's a suggested workaround
> define "A" do
>   package(:jar)
> end
> define "B" do
>   compile.with project("A")
>   test.with project("A").test.compile.target  # <---- HERE
>   package(:jar)
> end
> This works for the compile task, but it breaks the eclipse task.  It turns out that the generated .classpath contains an entry like
>   <classpathentry path="/Users/matteo/work/problematic/foo/target/test/classes" kind="src" excluding="**/.svn/|**/CVS/"/>
> that does not work in Eclipse.
> What can I do?

OK, I found a sort-of solution for both problems:

define 'problematic' do
  define 'foo' do
    package :war
  end

  define 'bar' do
    foo_src = project('foo').compile.target
    foo_test = project('foo').test.compile.target
    compile.with project('foo'), foo_src, foo_test
    eclipse.exclude_libs += [foo_src, foo_test]
  end
end

The first entry in compile.with is used by the eclipse task, to set up
the correct dependency on 'foo'.  The other two are used by the
compile task.  The eclipse.exclude_libs fixes the incorrect entries in
.classpath.

What do you think?

Matteo