简体   繁体   中英

subclassing an open-source library

I am using a large open source library and need to generate personal subclasses of a few of the classes. What are the best strategies? I would like to keep the original library unaltered and be easily able to reconfigure when it is updated. It is unlikely that my code is worth contributing to the project (though I am happy to write in a way that permits this).

The problem is a general one but I will illustrate it with my example. I am using Apache PDFBox which has a routine to write to java.awt.Graphics2D . I have replaced this by the Apache Batik toolkit which provides a subclass of Graphics2D ( org.apache.batik.svggen.SVGGraphics2D ) so I can capture the SVG representation. I create an instance

public static org.apache.batik.svggen.SVGGraphics2D createSVG() {
    org.w3c.dom.DOMImplementation domImpl =
    org.apache.batik.dom.GenericDOMImplementation.getDOMImplementation();
        org.w3c.dom.Document document = 
            domImpl.createDocument("http://www.w3.org/2000/svg", "svg", null);
        return new org.apache.batik.svggen.SVGGraphics2D(document);
    }

The place where PDFBox uses the graphics is org.apache.pdfbox.PDFReader which I have edited to allow for the new graphics:

    protected void showPage(int pageNumber)
{
    try 
    {
        PageDrawer drawer = new PageDrawer();
        PageWrapper wrapper = new PageWrapper( this );
        PDPage page = (PDPage)pages.get(pageNumber);
        wrapper.displayPage( page );
        PDRectangle cropBox = page.findCropBox();
        Dimension drawDimension = cropBox.createDimension();
        svg = PDFPagePanel.createSVG();          // MY EDIT!!!!!!!!!
        drawer.drawPage( svg, page, drawDimension );
        writeSVG(pageNumber);
    }
    catch (IOException exception)
    {
        exception.printStackTrace();
    }
}

I have got it to work (that's not the problem). My concern is that I have had to hack/edit and recompile a number of the distributed PDFBox classes simply to generate and use the subclass. I end up with classes such as PMRPDFReader in the same packages as the library. It's very messy - I can't immediately remember where I made the edits, etc.

I feel I ought ought to be able to use the library as-is and simply add/link my subclasses. I use maven so maybe there is a way of excluding the original classes.

If the library hasn't provided easy subclass hooks, then you don't have much choice. Given they have a git mirror, I'd just fork it (keep your mirror somewhere safe and backed up, preferably in close proximity to your normal SCM). My usual strategy is to append -companyName to the version number (in Maven) so that I can remember that it's a patched version. You can easily see what edits you made since they'll be in your revision history.

You can also investigate using the maven shade plugin to alter/replace classes but that's a bit hackier IMHO.

Here's how I would do this:

  • Create a separate project that contains your source code changes. Check it into source code/revision control (SVN, Git, whatever you're using). This project will only contain your changes.
  • Make sure it's a Maven project. Use the same version number as the original open source project, but add an appendix to the version. If you're using version 1.2 , create your project to have version 1.2-Peter-1 or something similar. This way, you'll always know which version it's based on you're also able to provide multiple versions/revisions of your changes. It will also not conflict with the official versions. Use the same group/artifact IDs as the official ones.
  • Use the original project as a dependency in your own.

For deployment, you then have two options:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM