Stop gradle from stepping on Eclipse's (long) toes

In the default setup of the workspace, the gradle build tool & eclipse share the same output directories. In general, this means you always have to clean in each tool and in the case of Eclipse stop the incremental builder.

All the output directories are defined in macros. In general, the ${target-dir} is the main output directory and the ${bin} and ${testbin} are placed inside this directory. So by redefining ${target-dir} in cnf/build/bnd we can redirect all output.

bnd has a macro ${driver} that indicates which build tool (a.k.a. the driver) is used. We can then use this as follows:

target-dir              target${if;${driver;eclipse};;/${driver}}
bin                     ${target-dir}/classes
testbin                 ${target-dir}/test-classes

Enjoy!

1 Like

Thanks for the hint, that would solve some toe-stepping :slight_smile:

Could you maybe add a hint where this can be added? Or a link to the relevant docu section?

When I place this in our ext/mybuild.bnd then it seems driver-modifier is not resolved. But I am new to macro definitions.

It is cnf/build.bnd.

About the unresolved macro, not sure what happens here. I’ve updated the code to use ${def;driver-modifier} but do not understand why that would be necessary. Will look at the code and come back.

Ok moved it to cnf/build.bnd but same.
Does it matter where I place it ? (at the beginning or end of the file?)

Using Bndtools 6.4.0.REL-202211291949-g25e4898

Hmm, embarrassing. As far as I can see it does work but it creates this superfluous directory. It seems that the following definition goes better (and is simpler):

  target-dir              target${if;${driver;eclipse};;/${driver}}

Place should not make a difference. Then again it puzzles me.

1 Like

Great, thank you. I can confirm, that with the following block in cnf/build.bnd and doing 1.) an Eclipse Build followed by 2.) a gradle build on command line the resulting folder / jar structure is like:

cnf/build.bnd:

target-dir              target${if;${driver;eclipse};;/${driver}}
bin                     ${target-dir}/classes
testbin                 ${target-dir}/test-classes

Results in:

  1. Eclipse builds the .jar in target root.
  2. Gradle creates a gradle-subfolder inside target where the .jar is placed.

This is a nice addition and will cause less confusion for developers wondering why their Eclipse starts rebuilding everything when they start a gradle clean build :slight_smile:

One addition / hint:

The default for target-dir seems to be generated when not defined. This has been the case for us.
In this case it may be a better idea to use the prefix generated instead of target like

target-dir generated${if;${driver;eclipse};;/${driver}}

, if you are used to find everything in the generated folder.

Also keep in mind that subsequent cli-build tooling (Jenkins, Ansible et. al) needs to be adjusted to the new /${driver} subfolder.

Only thing to be aware of is that sometimes, like in Github actions, the target folder is used to upload artifacts. This can be confusing since they’re not somewhere else than they used to be.

Anyway, thanks for the feedback!

1 Like

I created a PR for this. Add section about target-dir by chrisrueger · Pull Request #5584 · bndtools/bnd · GitHub as I think it could be helpful in the documentation.

Please review or make changes if you see fit. I was not sure where to place it exactly. If you know a better spot, feel free.

One thing I noticed much later, just in case it is relevant.

after I applied the changes above, Eclipse Problem view showed an error for each project:

Bndtools: src folder 'src/java/main' has output folder set to 'bin', which does not match bnd's bin folder 'generated/classes'

But it seemed that this had no negative impact. I could still launch my project from eclipse.

But I wanted the problems go away.
I could fix it by applying the following changes to all .classpath files in all projects.

Then all the problems were gone.
I guess before we have not defined target-dir, bin or testbind, so some defaults were used.

I’ve been longing to generate the .classpath properly from the bnd information. However, there was pushback to this idea because maybe some workspaces have private information in it. To me this is not worth the inconvenience to be so easily able to do it wrong.

A quick fix on the warning (with the repeat support) might be very useful. The code to generate the class file already exists.

m2eclipse uses an attribute on the classpath to determine if it is an automatically derived entry or a user entry

<classpathentry kind="src" output="target/classes" path="src/main/java">
	<attributes>
		<attribute name="optional" value="true"/>
		<attribute name="maven.pomderived" value="true"/>
	</attributes>
</classpathentry>

it seems fair enough that Bndtools uses a “bndtools.bnd.derived” attribute…

As a workaround for a clean/green workspace you can also ignore the warning… for the moment

-fixupmessages: \
  "Bndtools: src folder 'src' has output folder set to 'bin'"; is:=ignore

-fixupmessages: …

Yuck! :slight_smile: Always fix the root problem when possible, regardless of the amount of work. You, or the poor slobs coming after you will know why … :slight_smile: When you let yourself (or your workspace) go, it always surprises me how quick it gathers problems.

Having a clean hygienic workspace is such a wonderful feeling! :wink:

1 Like