Upcoming Classpath Changes

From: Mike Schrag (mschra..dimension.com)
Date: Sat Jan 19 2008 - 02:52:55 EST

  • Next message: Lachlan Deck: "Re: Upcoming Classpath Changes"

    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**.

    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.

    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.

    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.

    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. JavaWOExtensions comes from Library if you
    use Wonder. It always overrides JavaWOExtensions from System. If you
    don't want that, rename your conflicting framework.

    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. 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.

    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.

    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 ...

    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).

    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.

    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 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.

    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). 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.

    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.

    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).

    ms



    This archive was generated by hypermail 2.0.0 : Sat Jan 19 2008 - 02:54:41 EST