Bug 88887 - Problems with new project layout when importing jar'd projects
Summary: Problems with new project layout when importing jar'd projects
Status: RESOLVED FIXED
Alias: None
Product: PDE
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 major with 1 vote (vote)
Target Milestone: 3.1 M7   Edit
Assignee: PDE-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance
Depends on: 92550
Blocks: 89489
  Show dependency tree
 
Reported: 2005-03-23 12:20 EST by Dirk Baeumer CLA
Modified: 2005-04-27 17:26 EDT (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dirk Baeumer CLA 2005-03-23 12:20:31 EST
N20050323-0010

After importing jar'd projects into my workspace as binary projects I noticed
that the import now creates a class folder which contains every single class
file separately instead of one single jar. This has the following disadvantages:

- larger footprint on disk 
- slower startup times of the target workspace especially if you have a virus
  scanner activated.
- This adds significantly to the memory footprint of the development 
  workspace. In the old solution we had the jar files in the resource tree. Now
  we have every single class file in the resource tree.
Comment 1 Wassim Melhem CLA 2005-03-23 12:40:29 EST
You are importing a plugin with a . on its classpath, and you are getting a 
project with classes at its root.  The project compiles and runs fine.

PDE is the middle man and can't do anything about it  If you think this 
behavior is unacceptable, then this is philosophical discussion about JARd 
plugins and their adoption should be conducted with the runtime team.
Comment 2 Jeff McAffer CLA 2005-03-23 13:17:03 EST
The jar'd plugin approach moves us closer to the standard Java way of doing 
things.  This is one of the benefits.  The behaviour you are seeing is (I 
believe) the same as if you imported a standard Java jar into your workspace as 
a project (assuming that you can do that).  

We should step back from this a little and look at why you are importing as a 
binary project.  I'm guessing that standard Java developers generally do not 
import normal jars as binary projects .  

The historical driver was simplifying plugin classpath management.  PDE's 
classpath containers etc have pretty much solved that problem for some time 
now.  Other reasons that have come up relate to search, browsing and source 
lookup.  I believe that several of these are still issues.  As far as I can 
see, these problems relate to jars in general, and are not specific to 
plugins.  

Can you describe your workflow and use of binary import a little more so we can 
see if there are point or incremental solutions that improve on the points you 
made?
Comment 3 Dejan Glozic CLA 2005-03-23 13:26:20 EST
I am a bit nervious about the implications of this. It puts pressure on PDE to 
solve some long-standing problems in terms of external plug-ins management 
(which is not bad in its own right). However I would like people who use 
binary projects to move to external plug-ins because there is nothing to loose 
in the move, not because they are forced to. 

With the plug-ins in JARs, we are fundamentally changing the self-hosting 
landscape. Not only that binary projects are becoming very hard to create, but 
also importing with links is impossible. I don't see a way to restore a more-
less familiar binary project option with JARd plug-ins without writing 
additional PDE code in the sensitive area of plug-in import. 

I am not saying it is impossible, just forces our hand fairly late in the 
release.
Comment 4 Jeff McAffer CLA 2005-03-23 13:37:33 EST
I was actually focussing more on the Java side of the world.  Plugins are now 
just jars like any other Jar.  If issues related to searching, browsing, ... 
external Jars are resolved then they should be resolved for PDE as well.
Comment 5 Dirk Baeumer CLA 2005-03-23 13:42:29 EST
The reason why I import the plug-ins as binary project is easy: I want to have a
sandbox which is not affected by any changes I do to my developement
environment. ZRH does a plug-in export every day and we use it for self hosting.
So my development environment changes on a daily basis. And this shouldn't have
any impact on the content of my workspace.

The basis for the decision when to reference a jar and when to import it into my
workspace depends on how frequent it changes. So I wouldn't import rt.jar but I
want to import plug-ins to make sure that I can work in a sand box even if I
change my development environment.
Comment 6 Jeff McAffer CLA 2005-03-23 13:59:24 EST
Great usecase.  Would platform targets help you here?  For example, I never 
target my IDE because, like you, want control over the sand box.  Here sandbox 
= workspace + target.  In my case it is forced by RCP constraints etc. but the 
issues are similar.

When I start from scratch I get an I build for my IDE (c:\ide) and whatever I 
want for the target c:\target (typically the RCP SDC).  I start the ide and set 
the target to be c:\target.  They then checkout only the projects on which I 
want to work.  When I run I'm running the target install.

For you, you might get the full SDK and unzip twice, once for the target and 
once for the IDE.  

This approach gives you complete freedom to change the ide independent of the 
target.  Further, say you want to go to the next I build (assuming you 
currently sync up your workspace periodically), just delete c:\target and 
replace it.  No need to reimport the binary projects.

Does this make any sense or is it off in a different direction?
Comment 7 Dani Megert CLA 2005-03-23 17:07:25 EST
I also prefer to self host by importing the binary projects due to restrictions
that Jeff already pointed out in comment 2. It is a something that worked for us
and most likely for many others for a long time.
Comment 8 Jeff McAffer CLA 2005-03-23 17:53:44 EST
To be clear, it continues to work though with some issues as Dirk points out.  
I'm really not suggesting that people change the way they work but more trying 
to understand how they work and why.  

I agree totally with the comments from all of the D*s.  Hopefully between JDT, 
PDE and runtime we can enumerate the issues and potential solutions.  Wassim in 
particular has been working very hard to make the PDE tooling all that it can 
be and is very sensitive to people's development needs.  But there is only 
finite time.  Creative solutions in the JDT (UI and debug) space for dealing 
with external jars in general would likely help reach Dejan's goal of seamless 
migration and the other D*'s goal of equivalent behaviour.


Comment 9 Dirk Baeumer CLA 2005-03-24 08:34:02 EST
Regarding comment #6:

the setup makes sense, however it feels more complicated then what we do today.
Today I update by eclipse installation with our daily export run it for a while
and if it works I simply import the plug-ins form my installation. With an
external approach I have to do it twice. Additionally disadvantages of this
approach are:

- no stable project layout when you switch between source and binary projects
  (which I do at least once a week). Currently, both binary and source projects
  appear as normal projects. Using the PDE class path container to reference
  external Jars I always have to think about if I have a project in source or in
  binary to look into the right container.

- there are still problems how PDE manages the class path container (a good
  summary is in bug 79966) and I don't see an easy solution for this. 

I took a look at the layout of the jar'd plug-in and one solution would be to
change the way how PDE imports binary projects. I will outline what I have in mind:

- PDE creates a project with the name of the jar'd plug-in
- instead of expanding the jar it simply imports the jar and puts it onto the
  class path and attaches the source file.
- it copies the plugin.xml file out of the Jar and patches the library statement 
  (e.g change library name="." to library name="`plugin_name`.jar".
Comment 10 Wassim Melhem CLA 2005-03-24 10:30:29 EST
Dejan and I were discussing this possibility.  Although it would compromise 
the integrity of the plugin itself as we would be butchering its 
plugin.xml/manifest.mf, we were contempating doing it for the sake of 
uninterrupted workflows. 

However, a problem remains is that given a JARd plugin, all classes/resources 
are at the root of the JAR.  PDE has no clue how to reverse-engineer it:  ie 
what is supposed to be extracted to the root of the project and what is 
supposed to stay in the JAR.  

https://bugs.eclipse.org/bugs/show_bug.cgi?id=88559
Comment 11 Jeff McAffer CLA 2005-03-24 10:55:15 EST
Some thoughts:

- We can contrive to have the export problem just take the plugin jar that is 
in the project.  This would likely need some special markup but say
   bin.includes=@org.eclipse.foo_3.1.0.jar
where the @means that this the thing. (period).  the bin.includes would not 
have any other elements (or they would be ignored).

- Tom Watson brought up another point, what about launching.  When you run such 
a plugin you actually have to install the jar, not the dir.  Hacking the bundle 
classpath in the manifest in the dir is enough to make the compiler happy but 
if you install the project dir, what about the icons etc. that are expected to 
be files in the root of the plugin?  These are not accessed via getResource but 
rather getEntry

- So, why not go whole hog and just leave the plugin as is, cereate a project, 
add the jar to the project as a lib and have special cases for exporting and 
running.  In both cases you effectively ignore that it is a dir and install (in 
the case of running) or copy (in teh case of building) the pluigin jar itself.
Comment 12 Wassim Melhem CLA 2005-03-24 13:43:02 EST
Any suggestion that does not involve the end result being a workspace project 
with manifest files and other resources at the root of the project is a no go.

Therefore, we cannot make progress on this issue unless the JARd plugin 
contains a file which PDE can read to deduce what should be at the root of the 
project and what should remain in a JAR (or unzipped into a source folder - 
bug 88559).

I still have not heard a valid reason why supplying such a file 
(build.properties (full or trimmed-down) or the like) in the JARd plugin is 
not desirable.  
Comment 13 Dani Megert CLA 2005-03-24 15:51:47 EST
I was not involved in the spec of build.properties, but can someone with more
knowledge one this explain why this was mapped to a '.' instead of simply adding
a 'jared' attribute? In my opinion this would have allowed to provide this
featue and allow PDE tooling to do a good job. Please correct me if I'm on the
wron path.
Comment 14 Jeff McAffer CLA 2005-03-24 17:11:45 EST
Dani, not sure what part of build.propreties you are refering to but in general 
there are things like 
  source.foo.jar=<source dir locations>
  source..=<source dir locations>
Here the thing after the "source." is the classpath entry for which the 
following directories hold the source.  There can be many of these.  For jar'd 
plugins their actual classpath entry typically really is '.'.  

For bin.includes you previously put in there the name of the jar(s) and other 
things.  So, using the same rule ("replace your jar name with ."), the 
bin.includes entry becomes '.'.

To be clear, the . doesn't really mean . in the filesystem case.  It is 
effectively the same as your suggestion to use a special key like 'jared'.

Anyway, to comment 12.  yes, I was wondering about problems if the manifests 
were not in the root of the project as normal.  When you say "resources", what 
are you talking about?  Things like icons?  I guess you need these for 
validation in the extensions etc right?  

Having the build.properties in there is possible.  Question:  What we really 
need is to distinguish between code/resources and other stuff right?  So we are 
interested in the bin.includes line right?  Could we use the Export-Package 
list to determine the answer?  In the case that we are doing the classic export 
*, this list identifies all of the code in the plugin.  Anything not covered in 
the package list would be extracted and placed in the project.  The plugin Jar 
would remain attached to the project as normal etc.

The issues come up when we go to run or export.  In both of those cases we 
really want to use the jar not the project.  A thought here is to "know" that 
the project is one of these binary imports of a jar'd plugin and so when 
building the list of plugins to run (in the platform.xml or config.ini) or 
export (however that is listed), list the plugin JAR rather than the dir.  So 
the files in the project are just there to keep the tooling happy but otherwise 
the jar is the source for running/exporting.

Does any of that make sense?  None of the approaches is particularly 
appealling.  For 3.1 we should look for something that enables the usecases put 
forward but does not imply yet more heroic effort from the PDE team.
Comment 15 Dani Megert CLA 2005-03-29 16:50:23 EST
I was thinking along Wassim's comment 12 where the build.properties file would
be distributed. If it would also contain the old (unjared) information about
what goes into JARs then PDE could import the project.
Comment 16 Wassim Melhem CLA 2005-03-31 04:15:00 EST
>I was wondering about problems if the manifests were not in the root of the 
>project as normal.

This definition of a workspace plug-in being a project with a manifest at its 
root must remain intact.  Otherwise, we will have chaos and disasters, and I'm 
talking like those biblical disasters that only locusts survive :-).

First, more than 60% would have to be rewritten.
Second, would PDE have to scan all JARs in the workspace to see which are 
plugins and which are not.

>A thought here is to "know" that the project is one of these binary imports 
>of a jar'd plugin and so when building the list of plugins to run (in the 
>platform.xml or config.ini) or export (however that is listed), list the 
>plugin JAR rather than the dir.

Third, keep in mind that binary projects are good in that they are exempt from 
JDT and PDE builds.  however, they are still writable projects (if they are 
not linked).  So users can add and modify plugin.xml files if they want to.  
You don't want to get into a situation where the user starts modifying the 
plugin.xml and yet when he launches we pass the JARd plugin instead.

We cannot bend any of these basic self-hosting rules.

>When you say "resources", what are you talking about?  Things like icons?  I 
>guess you need these for validation in the extensions etc right? 
Yes, and we have multiple uses for them.  Most importantly, when you launch we 
pass the URL of the project to the runtime so these resources have to be at 
the root.  

>So we are interested in the bin.includes line right? 
Yes.

>Could we use the Export-Package list to determine the answer?
Not bad, but no.  What if a plug-in does not export any packages.  Also note 
that for plugins that have no manifest.mf, we do NOT analyze the jars as it is 
a huge overhead, so no export-package header is generated.


We need to have closure on this in the next week or else it would have to be 
deferred until 3.2

Here is the only feasible solution:

1. the JARd plugin contains some kind of marker file enumerating the (non-java)
files and folders that must go at the root of the plugin.
2. When PDE imports the plugin as binary, it extracts the list of files and 
folders from 1. at the root of the project and imports the JAR as-is. 
3. Since the code is now in a JAR, the '.' on the classpath is no longer 
correct.  Therefore, PDE will munge the plugin.xml/manifest.mf to make that 
change.  (This is the part that I hate doing the most)
4. The End.

Note that with this solution, the import with source problem would be solved 
as well.  In that case, we wouldn't munge the plugin.xml, the source would go 
under a src/ folder and the build.properties would be complete.

Comment 17 Jeff McAffer CLA 2005-03-31 18:09:33 EST
You've got an answer for everything don't you ;-)

Ok, it seems we have exhausted the options for the 3.1 timeframe and a flavour 
of what you suggest is what we have to do.  The thing I'm trying to avoid is 
having an extra file and some magic to create/maintain that file.  Let's go 
back to 

>>Could we use the Export-Package list to determine the answer?
>Not bad, but no.  What if a plug-in does not export any packages.  Also note 
>that for plugins that have no manifest.mf, we do NOT analyze the jars as it is 
>a huge overhead, so no export-package header is generated.

comment 16 suggested listing all the things in the plugin that are not code.  
Since there are only two kinds of things, code and not code, listing the code 
implicitly lists the not code.  (I just had to write that out).

The points you made against using the Export-Package list:
- what if no exports: If there really are no exports then everytihng in the 
plugin would be, by definition, not code and would be listed explicitly on the 
bin.includes line.  not code - no code = not code.

- the issue about no manifest.mf is harder.  In this case I suggest that if 
someone is importing such a plugin, we actually do the analysis 
(PluginConverter) and thus generate an Export-Package list.

The downside here is that pragmatically, a jar'd plugin with a plugin.xml will 
have . on the class path and export=*.  This means that in the end, the whole 
plugin will be exported and everything treated as code.  Under the current 
model, nothing will be imported.  I propose that we treat this as a 
pathological case and import the whole jar.  I.e., when in doubt, import it all.

The net of this approach is that none of the build process has to change.   
People do not have to release their dev-time files (build.properties) in the 
runtime, and we solve the main issues we have.

We could always have a backup mechanism for the pathological cases which is 
somewhat like you describe but it would be good not to require that everywhere.
Comment 18 Philipe Mulet CLA 2005-04-01 09:00:27 EST
So. Is this going to be addressed for 3.1 ? JDT/Core is also using binary
plugins (not linked) for the same reason Dirk mentionned. I also feel that
asking clients to change the way of working is as good as simply stating this
scenario is no longer allowed, which would be bad.

The current state of imported binary plugins is simply overkill, especially
considering the performance effort we are putting in for M7. 
Comment 19 Philipe Mulet CLA 2005-04-01 09:05:25 EST
Side-note: one direct consequence of this evolution is bug 89848. Though we were
able to address it, there may be more issues with this new setup, which has been
little tested before (as proved by existence of bug 89848); and we are getting
close to 3.1... so why changing rules right before a release ? We now that
imported binary plugins as JARs are working just fine.

Comment 20 Jeff McAffer CLA 2005-04-01 09:28:22 EST
philippe, I'm not sure what you are suggesting here.  Do you object to the 
proposals in comment 16 or comment 17?  If so, how and do you have a proposed 
alternative?
Comment 21 Wassim Melhem CLA 2005-04-01 09:32:26 EST
and now for the rebuttal :-)

>what if no exports: If there really are no exports then everytihng in the 
>plugin would be, by definition, not code and would be listed explicitly on 
>the bin.includes line.  not code - no code = not code.

Export-Package is not sufficient.
What if a JAR hypothetically has two sets of packages: ones that start with 
com.example.bla.* and others that start with private.monkey.* and the Export-
Package only want to expose the former.  All the private monkey classes will 
end up at the root of the plugin.


>the issue about no manifest.mf is harder.  In this case I suggest that if 
>someone is importing such a plugin, we actually do the analysis 
>(PluginConverter) and thus generate an Export-Package list.

Doing this analysis takes a couple of minutes for a target platform with 1000 
plugins.  So you will have to wait a couple of minutes when you want to 
proceed from the first to the second page.


>a jar'd plugin with a plugin.xml will 
>have . on the class path and export=*.  This means that in the end, the whole 
>plugin will be exported and everything treated as code.  Under the current 
>model, nothing will be imported.  I propose that we treat this as a 
>pathological case and import the whole jar.  I.e., when in doubt, import it 
>all.
That is what all the current JARd plugins that have a plugin.xml in the SDK 
look like. 

>The net of this approach is that none of the build process has to change.   
>People do not have to release their dev-time files (build.properties) in the 
>runtime, and we solve the main issues we have.

Time to add the build.properties to the bin.includes, save the file and 
release it into HEAD: 2 seconds.
Time to come up with alternate solutions: 8 days and counting :-)

When importing the content of the jar, I am not going to import the 
build.properties as-is, I will use it as a guideline and create a trimmed down 
version.
Comment 22 Philipe Mulet CLA 2005-04-01 09:54:39 EST
Re: comment#20
Reading through the PR, it wasn't clear to me whether this would be addressed
for 3.1, or rather deferred. If resolution is for 3.1, then I am fine with the
current direction.
Comment 23 Wassim Melhem CLA 2005-04-11 18:57:05 EDT
Moving to PDE/UI to resolve this issue.
In return, I get custody of Jeff's boat for the month of August.
Comment 24 Jeff McAffer CLA 2005-04-11 21:31:43 EDT
sure if you want to come up and do all the spring maintenance/cleaning...
Comment 25 Dirk Baeumer CLA 2005-04-25 19:11:26 EDT
Thanks !!
Comment 26 Dirk Baeumer CLA 2005-04-25 19:12:36 EDT
Oops I thought it got fixed, but 92550 got fixed. But given this is fix isn't
far away...
Comment 27 Wassim Melhem CLA 2005-04-27 04:29:59 EDT
Done.  Will appear in the next nightly build.

When importing a JARd plugin, we will:
1. extract the non-Java resources to the root of the plugin
2. import the JARd plugin as-is into the project.
3. modify the manifest.mf of the project to reference JAR from 2 not '.'

In the case of a linked import, in step 2, we will link to the external JAR.

Importing as source is also back to normal now.  We will extract the java 
files into a source folder, not at the root of the project.
In the case of import with source, we don't modify the manifest.mf.  We just 
map the '.' to the source folder in the build.properties file.

This effort took an insane amount of work.
It's a testament to show how far a guy would go for a boat ride :-)
I should be eligible to become a pope now.  I pick the name Pius.
Comment 28 Dirk Baeumer CLA 2005-04-27 04:58:22 EDT
Thanks !!
Comment 29 Dani Megert CLA 2005-04-27 05:04:23 EDT
Cudos for Pius!
Comment 30 Dani Megert CLA 2005-04-27 05:40:15 EDT
What plug-ins do I need from HEAD to get this? I just took org.eclipse.pde.ui
from HEAD and it imported each class file so I guess I also need HEAD of some
other plug-in(s).

And of course Kudos, not cudos!
Comment 31 Wassim Melhem CLA 2005-04-27 08:58:47 EDT
it's still in a branch (Binary_Import).  You would need pde.core and pde.ui.  
will release into HEAD later on today.
Comment 32 Jeff McAffer CLA 2005-04-27 17:26:50 EDT
You can definitely steer the boat.  We'll even set up the BBQ!