Java 对开源库进行子类化

Java 对开源库进行子类化,java,maven,open-source,subclass,Java,Maven,Open Source,Subclass,我正在使用一个大型的开源库,需要生成一些类的个人子类。最好的策略是什么?我希望保持原始库不变,并且在更新时能够轻松地重新配置。我的代码不太可能值得为项目做出贡献(尽管我很乐意以一种允许这样做的方式编写代码) 这个问题是一个一般性的问题,但我将用我的例子加以说明。我正在使用它,它有一个例程要写入java.awt.Graphics2D。我用Apache工具包代替了它,它提供了Graphics2D的子类(org.Apache.batik.svggen.SVGGraphics2D),因此我可以捕获SVG

我正在使用一个大型的开源库,需要生成一些类的个人子类。最好的策略是什么?我希望保持原始库不变,并且在更新时能够轻松地重新配置。我的代码不太可能值得为项目做出贡献(尽管我很乐意以一种允许这样做的方式编写代码)

这个问题是一个一般性的问题,但我将用我的例子加以说明。我正在使用它,它有一个例程要写入
java.awt.Graphics2D
。我用Apache工具包代替了它,它提供了Graphics2D的子类(
org.Apache.batik.svggen.SVGGraphics2D
),因此我可以捕获SVG表示。我创建了一个实例

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);
    }
PDFBox使用图形的位置是
org.apache.PDFBox.PDFReader
,我已经编辑了该位置以允许使用新图形:

    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();
    }
}
我已经让它工作了(这不是问题)。我担心的是,为了生成和使用子类,我不得不对一些分布式PDFBox类进行黑客攻击/编辑和重新编译。我最终得到了与库相同的包中的类,如PMRPDFReader。这是非常混乱的-我不能立即记得我在哪里做的编辑,等等


我觉得我应该能够按原样使用库,只需添加/链接我的子类。我使用maven,所以可能有一种排除原始类的方法

如果库没有提供简单的子类钩子,那么您没有太多选择。考虑到他们有一个git镜像,我就用叉子把它叉起来(把镜像放在安全的地方并备份,最好是放在离普通SCM很近的地方)。我通常的策略是在版本号后面附加-companyName(在Maven中),这样我就可以记住它是一个补丁版本。您可以很容易地看到所做的编辑,因为它们将出现在您的修订历史记录中


您也可以研究使用maven shade插件来更改/替换类,但这有点太过粗糙了。

下面是我的做法:

  • 创建包含源代码更改的单独项目。将其签入源代码/版本控制(SVN、Git,无论您使用什么)。此项目将仅包含您的更改
  • 确保这是一个Maven项目。使用与原始开源项目相同的版本号,但在版本中添加附录。如果您使用的是1.2版,请创建项目,使其具有1.2-Peter-1版或类似版本。这样,您将始终知道它基于哪个版本。您还可以提供更改的多个版本/修订。它也不会与官方版本冲突。使用与官方相同的组/工件ID
  • 将原始项目用作您自己项目中的依赖项
对于部署,您有两个选项:

  • 部署您的JAR(其中只包含您的更改)和原始JAR,但确保您的JAR位于类路径中的第一个
  • 使用Maven Shade插件创建一个混合原始类和您自己的类的jar:

谢谢。他们显然希望人们将子类化,但我还没有看到明确的钩子(接口、依赖注入等),如果他们只是为了创建钩子,他们可能会非常愿意接受你的补丁。当我让它整洁地工作时,我肯定会在他们的列表中提到它