Re: Upcoming Classpath Changes

From: Peter Pritchard (pjpritc..ac.com)
Date: Sat Jan 19 2008 - 10:44:57 EST

  • Next message: Mike Schrag: "Re: Upcoming Classpath Changes"

    Before I say anything ... anything better is well ... better ...

    That being said ... My $0.02 ...

    For exact versions of frameworks, we use svn:externals to build
    frameworks, where the framework project lives in PROJECT_ROOT/
    Dependencies/Frameworks and the build.xml file of the project runs the
    build.xml of the dependencies, placing the compiled frameworks into
    PROJECT_ROOT/Frameworks.

    This has worked out well for us. Everyone who checks out the project,
    also (automatically) checks out the versioned framework.

    Our build.XML file adds a framework fileset for 'project local'
    frameworks and sets embed=true.

    Now if Wolips recognized the project itself as a place to find
    frameworks ...

    Development would be treated just like deployment.

    And yes, I stole the idea from Rails ... Freezegems ...

    - PJ

    Btw >>> I had to do tricks to get split install to work right with
    this technique and handle deep dependencies and recursive inclusions
    properly.

    For us, it works the same in dev as deploy, but I long for the day
    when I get to throw out my custom ant tasks.

    Sent from my iPhone

    On Jan 19, 2008, at 9:47 AM, Lachlan Deck <lachlan.dec..mail.com>
    wrote:

    > On 19/01/2008, at 6:52 PM, Mike Schrag wrote:
    >
    >> I wanted to go over the new classpath system that will be coming in
    >> sometime in the next few days, because it's a pretty huge change
    >> and it **will require you to change your build scripts and possibly
    >> modify your project build paths**.
    >
    > Necessary pain for a better system...
    >
    >> The management of classpath in WOLips/woproject is very complicated
    >> and has been the source of constant problems and confusion for a
    >> long time. It's been through many (many) changes, but it seems to
    >> never really behave in an intuitive way. I really wanted to
    >> approach it from a new perspective to try to make it all work the
    >> way I think people typically expect it to.
    >
    > And the crowd says 'Hooray!'
    >
    >> There are several problems that I wanted to address with the new
    >> design.
    >>
    >> Problem #1 - Project vs Framework
    >> This is a long-standing problem. You have installed frameworks
    >> that you link against from the WebObjects Framework classpath
    >> container and you have projects with source code that you link
    >> against inside of Eclipse. If you want to deploy using the
    >> standard build scripts, you have to have both, but those have to be
    >> in the right order or terrible things happen.
    >>
    >> Problem #2 - Classpath Ordering
    >> In the old system, there was a single classpath container that
    >> represented all of the frameworks that you link against. This ends
    >> up being pretty strange because you can neither reorder the
    >> frameworks within that container, nor can you reorder between the
    >> WO container and non-WO frameworks.
    >>
    >> Problem #3 - Live Change Detection
    >> The current system caches the list of frameworks that you have
    >> installed and never updates them. If you install a new framework,
    >> it has no idea.
    >
    > Worse... we found that when another developer checks out the project
    > from svn and imports into Eclipse that WOLips *silently* removes
    > from the classpath any references to frameworks not installed on
    > that particular system. That's really bad.
    >
    >> Problem #4 - Deployment vs Development
    >> Development happens with the incremental builder, deployment
    >> happens with ant. Classpath for ant is managed with those ..$
    >> ant.* files. You know those files. They're the ones always causing
    >> conflicts in your version control system. They're also the ones
    >> that always manage to have really weird references to jar files
    >> that exist on your system and nobody else's.
    >>
    >> Problem #5 - wobuild.properties
    >> I hate this file. Nobody knows what is supposed to be in it and
    >> what isn't. You should never have to think about it unless you're
    >> doing something weird. This includes Windows.
    >>
    >> Problem #6 - Source Jars
    >> It would be nice to have this just work.
    >>
    >> ... which leads us to the new system. One of the things that I
    >> have been leaning more towards is the Rails-ish "convention over
    >> configuration". In some cases this results in a loss of power, but
    >> in exchange for the system being substantially easier. None of this
    >> is committed, however, so I'm totally open to discussions on it.
    >
    > It should reduce confusion for new adopters too, mailing list
    > discussions / etc, not to mention if some new developer picks up a
    > project the mystery is reduced.
    >
    >> Solutions #1, #2, and #3 - Project vs Framework, Classpath
    >> Ordering, and Live Change Detection
    >> Welcome to our first convention over config -- Framework
    >> precedence. Project, External Build Root, User Frameworks, Local
    >> Frameworks, System Frameworks. This is the order frameworks resolve
    >> when referenced by name. Period.
    >
    > Should we include /Network as the last stop?
    >
    >> JavaWOExtensions comes from Library if you use Wonder. It always
    >> overrides JavaWOExtensions from System. If you don't want that,
    >> rename your conflicting framework.
    >
    > How do you deal with differing versions installed on different
    > machines? i.e., how to validate that the version installed has the
    > assumed fixes?
    >
    > Perhaps if we could have a preference saved with the project that
    > could optionally define a custom domain/dir where frameworks could
    > optionally be resolved. So that would mean something like:
    > Project, External Build Root, *Custom Frameworks as defined by
    > Project*, *Custom Frameworks as defined by Workspace*, User
    > Frameworks, Local Frameworks, System Frameworks.
    >
    > Just a thought.
    >
    >> And now the big overhauls inside Eclipse ... Frameworks resolve
    >> dynamically. If your application depends on ERExtensions and you
    >> have the ERExtensions project checked out, we resolve against the
    >> project. If you close the project, we switch and resolve against /
    >> Library/Frameworks/ERExtensions.framework.
    >
    > I'm hoping you meant 'we switch to resolve against whichever is
    > found first... ~/Library/Frameworks/ERExtensions.framework, /Library/
    > Frameworks/ERExtensions.framework... etc. Same goes for
    > JavaWOExtensions (even if using WOnder).
    >
    >> If you don't have the project checked out and you check it out of
    >> Wonder's CVS, all of your projects will switch on-the-fly to use
    >> the checked out version. No more juggling because some team members
    >> use the installed version and some use the project ones.
    >
    > Sure. Any suggestions on being able to enforce a minimum or exact
    > version of a framework?
    >
    >> Frameworks are now individual classpath containers. This more
    >> closely matches how WO represents them internally -- each is a
    >> bundle containing its jars and classes. This also means that you
    >> can order frameworks individually and reorder them relative to
    >> projects individually.
    >> <Picture 2.png>
    >> You can manage your WO frameworks much more directly in that you
    >> can simply right click on a framework in your project => Remove
    >> From Build Path, and you can right click => Add Library =>
    >> WebObjects Frameworks ...
    >> <Picture 1.png>
    >> Because framework precedence is now used, the tree view of
    >> frameworks is gone. There is now only the list of frameworks that
    >> are available to you, and the second column lets you know where it
    >> is loading from at the moment on your machine.
    >>
    >> Additionally, because each framework is a separate container, the
    >> classpath format is much cleaner. .classpath files now looks like:
    >>
    >> <classpathentry exported="true" kind="con" path="WOFramework/Ajax"/>
    >> <classpathentry exported="true" kind="con" path="WOFramework/
    >> ERAttachment"/>
    >> <classpathentry exported="true" kind="con" path="WOFramework/
    >> ERExtensions"/>
    >> <classpathentry exported="true" kind="con" path="WOFramework/
    >> ERJars"/>
    >> ...
    >>
    >> Because WOLips is now managing framework projects, you may need to
    >> modify your build paths to remove duplicate project references the
    >> old style (though the classpath converter should automatically do
    >> this when you open a project using the new build).
    >
    > Nice.
    >
    > Something to think about... it's fairly standard practice nowadays
    > to embed all frameworks, including wo-system ones, in a deployed app
    > so as to avoid having to simultaneously update applications that
    > depend on one or more frameworks of the same name when those
    > framework versions change.
    >
    > On a development machine, however, where its common to regularly
    > jump between, or have the projects for these disparate applications
    > open simultaneously within Eclipse.... how might this be achieved
    > with minimal pain? e.g., one project could depend on WO5.4 and
    > WOnder for WO5.4, and another for WO5.3 etc.
    >
    > This is the problem with the assumption, I suppose, that the
    > frameworks are, often, assumed to be in /Library.
    >
    > It'd be really nice to be able to have two such projects open at the
    > same time without a constant need of closing one down, running some
    > script to update the OS installation, etc.
    >
    > So that raises a question about the above suggestion of
    > automatically using the Project if it's open, say for ERExtensions
    > vs the installed one. Should there be an easy way to switch that on/
    > off for a project (like a switch/flag) so you don't have to
    > continually close/open something in order to test different
    > conditions?
    >
    >> The contents of /Library/Frameworks (et al) reload on-the-fly as
    >> well. If you install a new framework, it will be immediately
    >> available from the list of frameworks to choose from. One other
    >> small change in the UI is that the "Add WebObjects Framework"
    >> dialog (above) doesn't show frameworks that already are added, only
    >> new ones you can add.
    >
    > Nice.
    >
    >> On thing that trip people up is that because frameworks can be
    >> interleaved with other project dependencies, depending on your
    >> project export definitions and the particular ordering, you may run
    >> into problems that require you to reorder your classpaths. For
    >> instance, ERExtensions has to come before JavaWebObjects because it
    >> replaces NSArray/NSDictionary/NSSet. In the new system you may
    >> find that one of your projects either isn't exporting all of its
    >> dependencies properly or doesn't have its dependencies ordered
    >> properly. Just make a mental note -- if you upgrade and get a
    >> bunch of errors about generics not working, just push ERX higher in
    >> the build order -- it means one of your dependencies imported
    >> JavaWebObjects before you loaded ERX.
    >>
    >> Solution #4 and #5 - Development vs Deployment and wobuild.properties
    >> This will be one the big change for people. ~/Library/
    >> wobuild.properties is now ~/Library/Application Support/WOLips/
    >> wolips.properties (or equivalent on Windows). The keys in it are
    >> now normalized naming and only contain the things that matter. For
    >> instance, mine is:
    >>
    >> wo.apiroot=/Developer/ADC%20Reference%20Library/documentation/
    >> WebObjects/Reference/API/
    >> wo.appsroot=/Library/WebObjects/Applications
    >> wo.bootstrapjar=/System/Library/WebObjects/JavaApplications/
    >> wotaskd.woa/WOBootstrap.jar
    >> wo.localroot=/Library/Frameworks
    >> wo.systemroot=/System/Library/Frameworks
    >> wo.userroot=/Users/mschrag/Library/Frameworks
    >>
    >> However, I didn't actually touch this file, it was made
    >> automatically with sane defaults. There will likely be a WOLips UI
    >> for this at some point, but this rarely needs to be changed so it
    >> might not be worth it. Unfortunately this can't be stored purely in
    >> WOLips preferences, because ant DOES need access to this file. The
    >> ant tasks will also automatically create this file (using the same
    >> code and same defaults) if it doesn't exist. There are also sane
    >> Windows defaults for these.
    >>
    >> There are changes to the build.xml files as a result of this
    >> one ... The default build files have some validation checks for the
    >> old names (wo.wolocalroot, which is now wo.localroot, etc) and lots
    >> of references to the old names.
    >>
    >> The other annoying thing that has plagued wolips ant building are
    >> those ant.* files. They are gone (unless you want to use them on
    >> your own for custom classpath loading or if you don't use eclipse).
    >>
    >> If you use eclipse as your development environment, the wolips ant
    >> tasks now load classpath dependencies out of the Eclipse .classpath
    >> file for your project
    >
    > Nice.
    >
    >> and applies the exact same framework precedence rules for resolving
    >> frameworks. All of the old framework references now look like:
    >> <woapplication ..>
    >> ...
    >> <frameworks root="User" embed="true" eclipse = "true"/>
    >> <frameworks root="Local" embed="true" eclipse = "true"/>
    >> <frameworks root="System" embed="false" eclipse = "true"/>
    >> </woapplication>
    >>
    >> The eclipse = "true" attribute tells the woproject ant tasks that
    >> it should load the information for the particular framework root
    >> from the .classpath file and reference or embed based on the
    >> framework precedence of the frameworks in .classpath. For
    >> instance, if your .classpath refers to WOFramework/Ajax, it will
    >> look in User, then Local, then System to find that framework. The
    >> framework ant task is still a fileset, so you can leave off eclipse
    >> = "true" and manually define the include sets if you want.
    >>
    >> Order is preserved.
    >> Did you hear that? I'll say it again ...
    >> Order is preserved. The order that you define your frameworks in
    >> Eclipse will match the order your framework jars will appear in
    >> MacOSClasspath.txt.
    >
    > Hooray!
    >
    >> Now the one catch here ... The ant build system doesn't know about
    >> Eclipse (right now). This means that building an installed version
    >> of a framework or a deployment version of your application, cannot
    >> resolve frameworks against the Project versions (because of
    >> embedding, it would have to be able to kick off the build of the
    >> dependent framework's build.xml inside the project, and then
    >> install from there -- possible, but just sort of tricky right now).
    >
    > Look forward to that one. :-)
    >
    >> The side effect of this is that if you are running with Project
    >> versions winning in precedence, if you perform a build with ant,
    >> you must install the project versions into /Library/Frameworks (or
    >> your User framework folder) for it to be found and embedded in the
    >> build. This is no worse than things are now, just slightly
    >> unintuitive given that inside of Eclipse it will dynamically
    >> resolve against a Project.
    >
    > Yep, same as now.
    >
    >> Solution #6 - Source Jars
    >> In your built frameworks, if you name a jar src.jar, it will be
    >> automatically associated as the source jar for your framework. For
    >> each jar in your framework, you can make a thatname-src.jar and it
    >> will be used as the source jar for the built jar. For instance, if
    >> you have somexmllib.jar in your framework and somexmllib-src.jar in
    >> your framework, the src jar will be attached to the binary jar so
    >> Eclipse can resolve source files. This is the only way it works.
    >> The is no override. Rename accordingly.
    >
    > Cool.
    >
    >> I know this is a drastic set of changes, but I really feel like
    >> these problems have been a pain in the butt for everyone for a long
    >> time, and hopefully this will make a lot of systemic problems go
    >> away. This is not to say there won't be bugs in this
    >> implementation -- it's lots of changes that touch lots of code, but
    >> I think it puts us on a better trajectory that will be worth the
    >> shake up.
    >>
    >> .classpath files WILL change after this upgrade (again it is NOT
    >> committed yet). This means that everyone on your team needs to
    >> upgrade together, or you need to avoid committing your .classpath
    >> files so you don't stomp on theirs.
    >>
    >> Also, because the build process redefines quite a bit (new
    >> properties files, new variable names, etc), your existing build.xml
    >> WILL break if you use the new woproject.jar. There is no problem
    >> keeping an old version of woproject.jar around to build your
    >> projects in the meantime, however (in fact, up until this rev, I
    >> have used some unknown ancient version to build all of our projects).
    >
    > All sounds like great improvements. Thanks very much Mike.
    >
    > with regards,
    > --
    >
    > Lachlan Deck
    >



    This archive was generated by hypermail 2.0.0 : Sat Jan 19 2008 - 10:46:20 EST