天道酬勤,学无止境

Best Practice for including 3rd party jars in a core library?

We have a core library that we include as a JAR with all of our web applications to maximize code reuse. Now we'd like to include some functionality through this core library via a 3rd party library (iText).

Adding the iText JAR to the core library doesn't work because nested JARs aren't found by the classloader. We don't want to add the iText JAR to each Web Application because the web applications aren't using iText, They are using a library that is using iText. Semantics? Perhaps, but adding third party JARs to a Web App so a library it uses can access the classes in the JAR seems messy.

Am I missing a simple practice that addresses this or are jar-merging and custom class loaders the best approaches?

标签

评论

Welcome to JAR hell, an ongoing issue in Java development, and one of the main reasons that OSGi is gaining steam. "Messy" approaches have been standard in the industry until only very recently, and the costs of clean approaches may well outweigh the cost of the quick and dirty approach.

But to answer your question, most app servers have a place where you can put JARS that are accessible across all web apps. Tomcat, for instance, has the common/lib directory. You probably want to put your JAR there.

An EAR would probably be the appropriate thing for this. Nothing like another layer of indirection.

If you distribute wars, you will have to place iText jar inside the war.
If you distribute ears, you can place all jars common to multiple wars inside ear root.
If jar is common to many ears, there is an option to place it inside web server library dir. This final option is not recommendable in my opinion, since you might use different versions of jar in each ear, thus producing conflict, and placing jar inside server root is generally not standard distribution mechanism.
There are tools that will repack all of your libraries and embed them into the single jar like Jar Jar Links.
Finally, I recommend using Maven or similar tool to manage your dependencies and automate your builds. It can be of great help as dependencies start to grow in number.

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Best Practice for loading 3rd party JARs in JBoss AS7 standalone deployment?
    What is the best practice for loading 3rd party JARs in JBoss-as-7.0.x standalone deployment? I have tried: deploying each JAR as an independent module with it's own module.xml desriptor; deploying the JARs in the WEB-INF/lib directory of a WAR; and the foo.ear/lib directory for any JARs shared across multiple WARs. The obvious advantage to approach 1. above is the reduced memory footprint at deploy time over apprach 2. and approach 3. However it seems to be pretty arduous to maintain as each dependency that a JAR has needs to be explicitly defined in the module.xml which doesn't seem very
  • How can I add a 3rd-party library to an Android AOSP build?
    I am trying to add the Jackson JSON library to my AOSP project. I am able to compile my project and flash it to a phone, but I get a runtime error: E/JavaBinder( 1689): java.lang.NoClassDefFoundError: Failed resolution of: Lcom/fasterxml/jackson/core/JsonFactory; ... E/JavaBinder( 1689): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.fasterxml.jackson.core.JsonFactory" on path: DexPathList[[zip file "/system/framework/guice.jar", zip file "/system/framework/beanshell.jar", zip file "/system/framework/services.jar", zip file "/system/framework/ethernet-service.jar", zip
  • OSGI-处理捆绑包所需的第三方JAR(OSGI - handling 3rd party JARs required by a bundle)
    问题 我才刚刚开始进行OSGI开发,并且正在努力了解如何最好地处理依赖的JAR。 即,如果我要创建捆绑包,则很有可能需要使用一些第三方JAR。 当我创建要部署到OSGI的捆绑包JAR时,显然不包括这些第三方JAR,因此捆绑包将无法运行。 我知道一种选择是将这些JAR打包成捆,然后将它们部署到OSGI容器中。 但是,如果只需要一个捆绑包使用它们,这似乎并不理想。 最好的解决方案是什么? 可以将JAR嵌入捆绑的JAR中吗?如果可以,这是否合理? 回答1 我几乎总是将每个罐子捆绑在一起。 OSGi本身就是为了模块化而设计的,您不这样做就使整个系统显得荒唐可笑。 如果要将JAR转换为捆绑包,则可能要使用Peter Kriens编写的BND工具。 但是首先,我建议您在SpringSource Enterprise捆绑软件存储库中寻找该捆绑软件,如果他们还没有为您完成工作。 回答2 通过将第三方jar添加到bundle jar文件的根目录中,然后将bundle classpath头添加到bundle的清单中,可以将第三方jar包含在bundle中。例如: Bundle-ClassPath: .,my3rdparty.jar 如果要将第三方jar放在子目录中,请在不使用标题./的情况下指定路径,例如 Bundle-ClassPath: .,lib/my3rdparty.jar # (not
  • 支持和反对在版本控制中包含第三方库的争论吗? [关闭](Arguments for and against including 3rd-party libraries in version control? [closed])
    问题 关门了。 这个问题是基于意见的。 它当前不接受答案。 想要改善这个问题吗? 更新问题,以便可以通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 改善这个问题 我最近遇到了很多人,他们说第三方库不属于版本控制。 这些人还无法向我解释为什么不应该向我解释,所以我希望你们可以来救我:) 我个人认为,当我检查项目的主干时,它应该可以正常工作-无需去其他站点来查找库。 通常,您最终会为不同的开发人员使用同一个第三方库的多个版本,并且有时会遇到不兼容的问题。 在这里建立一个libs文件夹是否很糟糕,其中包含您可以引用的“保证工作”库? 回答1 在SVN中,有一种模式用于存储称为供应商分支的第三方库。 同样的想法适用于任何其他类似SVN的版本控制系统。 基本思想是,将第三方源代码包含在其自己的分支中,然后将该分支复制到主树中,以便可以轻松地在本地自定义项上应用新版本。 它也干净利落地使事情分开。 恕我直言,在您的树中直接包含第三方内容是错误的,但是供应商分支可以达到很好的平衡。 回答2 是的,您应该(在可行时)。 您应该能够使用一台崭新的机器并以尽可能少的步骤来构建项目。 对我来说是: 安装IDE(例如Visual Studio) 安装VCS(例如,SVN) 查看建造 任何其他事情都必须有很好的理由。 这是一个示例:我有一个使用Yahoo的YUI压缩器来最小化JS和CSS的项目。
  • 在Maven阴影jar中包含第3方jar,而无需将其添加到本地存储库(Having a 3rd party jar included in Maven shaded jar without adding it to local repository)
    问题 我已经在 Stack Overflow 上找到了如何在项目中包含第 3 方 JAR 而不将其安装到“本地存储库”的答案: 我可以将 jars 添加到 maven 2 构建类路径而不安装它们吗? 但是,当我使用 Maven Shade Plugin 创建一个包含项目所有依赖项的 JAR 时,不会自动包含第 3 方 JAR。 我如何才能使Maven Shade插件在阴影JAR中添加这样的第三方JAR? 根据得到的答案,我让它工作了。 我所做的是,将这个片段添加到我的 pom.xml 的开头: <repositories> <repository> <id>repo</id> <url>file://${basedir}/repo</url> </repository> </repositories> 然后为我的项目添加了一个依赖项,也添加到 pom.xml: <dependencies> <dependency> <groupId>dummy</groupId> <artifactId>dummy</artifactId> <version>0.0.0</version> <scope>compile</scope> </dependency> </dependencies> 然后运行命令行将包添加到“repo”: mvn org.apache.maven.plugins
  • 如何在Glassfish中使用第三方库?(How to use 3rd party libraries in glassfish?)
    问题 我需要从运行在glassfish 3.0.1上的EJB3应用程序连接到MongoDB实例。 Mongo项目提供了一组驱动程序,我可以在独立的Java应用程序中使用它们。 我将如何在Java EE应用程序中使用它们? 也许是更好的措辞:当我的应用程序在EJB容器中运行时,如何使我的应用程序可以使用第三方库? 目前,在部署尝试从库中导入的Bean时,出现了java.lang.NoClassDefFoundError: [#|2010-03-24T11:42:15.164+0100|SEVERE|glassfishv3.0|global|_ThreadID=28;_ThreadName=Thread-1;|Class [ com/mongodb/DBObject ] not found. Error while loading [ class mvs.core.LocationCacheService ]|#] [#|2010-03-24T11:42:15.164+0100|WARNING|glassfishv3.0|javax.enterprise.system.tools.deployment.org.glassfish.deployment.common|_ThreadID=28;_ThreadName=Thread-1;|Error in annotation
  • How to use 3rd party libraries in glassfish?
    I need to connect to a MongoDB instance from my EJB3 application, running on glassfish 3.0.1. The Mongo project provides a set of drivers, and I'm able to use them in a standalone Java application. How would I use them in a Java EE application? Or maybe better phrasing: how would I make a 3rd party library available to my application when it runs in an EJB container? At the moment, I'm getting a java.lang.NoClassDefFoundError when deploying a bean that tries to import from the library: [#|2010-03-24T11:42:15.164+0100|SEVERE|glassfishv3.0|global|_ThreadID=28;_ThreadName=Thread-1;|Class [ com
  • AIR 3 Native Extensions for Android - Can I/How to include 3rd party libraries?
    With all the new hype surrounding native extension support in AIR 3, I haven't found a single thing that confirms or denies it is possible to include and use an external JAR inside the native Android implementation. All of the examples basically showcase the ability to hook into the built-in Android APIs. But what if someone wants to use one of hundreds of libraries that make it easier? Certainly it seems like this should be possible. I'll try to outline what I've done and maybe someone will spot a flaw: Successfully created native Android library, using compiled-in imports from 3rd party
  • 如何将图书馆与我的罐子结合起来?(How to combine library with my jar?)
    问题 好的,所以我编写了一个利用第三方开放源代码库的程序,并且希望将其与我的程序一起打包在一个jar中。 我正在使用netbeans 6.8,而我尝试过的Java总是将错误吐回去: java.lang.NoClassDefFoundError: libraryname; 主题之外:如果可能的话,我也想知道如何通过netbeans创建一个可执行的jar(exe)。 (看到的用Java编写但是.exe的程序) 编辑发现了一个名为FatJar的eclipse插件,它可以满足我的要求,但是我找不到与netbeans类似的东西,有这样的东西吗? 回答1 我将从强制性免责声明开始: Java可执行JAR无法以这种方式工作。 可执行JAR在JAR的MANIFEST.MF文件中定义了一个主类,而MANIFEST还允许对类路径进行定义,以包含可执行JAR中的代码将需要的库。 清单中的类路径定义必须枚举要放在类路径上的每个JAR或文件夹,相对路径是相对于可执行JAR的位置的,而不是相对于可执行JAR内部包含的路径。 可执行的JAR使用java可执行文件的“ -jar”参数启动,并且java“ -cp”标志和CLASSPATH环境变量均被忽略。 至于为什么以这种方式设计可执行JAR,您应该意识到从JAR中包含的JAR加载类的主要缺点,尽管此答复的其余部分将仅专注于这样做。 注意
  • 如何在Ant中动态包含ant-contrib.jar(How to include ant-contrib.jar dynamically in Ant)
    问题 我正在寻找一种在Ant文件中包含.jar的方法,以便可以立即使用它并在目标中调用其方法。 就我而言,它是ant-contrib-1.0b3.jar 。 回答1 最好的方法是将Ant-Contrib jarfile放入项目中。 例如,假设build.xml在项目的根目录中。 在项目内部创建一个名为ant.lib\ant-contrib的目录,然后将ant-contrib*.jar放在此文件夹中。 您可以将此方法用于可能需要的其他可选Ant任务(例如,Ivy,Findbugs,Cobrrtura等)。 然后,在build.xml文件中,您可以执行以下操作: <taskdef resource="net/sf/antcontrib/antlib.xml"> <classpath> <fileset dir="${basedir}/ant.lib/ant-contrib"/> </classpath> </taskdef> 我喜欢这样做,因为项目中包含了带有任务的可选罐子。 如果您将所有内容都检入版本控制系统中,则有人可以检出您的代码,并且无需下载Ant-Contrib并自行安装即可进行构建。 您可以定义XML名称空间。 这为您的Ant-Contrib任务提供了前缀,以防在您使用其他具有相同任务名称的可选ant任务的情况下避免任务名称冲突。 此外,它还会警告用户这不是标准的Ant任务
  • 在Eclipse-CDT中使用*相对*路径引用第三方库(Referencing 3rd party Libraries using *relative* paths in Eclipse-CDT)
    问题 在Eclipse-CDT中使用相对路径引用第三方C ++组件(例如,包含库)的最佳实践是什么? 我正在尝试引用Boost和Google protobuf。 我已经将它们分别放在工作区的文件夹中,例如/ home / user / workspace / boost_1_39_9 我在项目属性的构建设置下添加了对该文件夹的引用,但是Eclipse无法让我指定相对于工作空间文件夹的路径,我必须使用文件系统选择它并指定一个绝对路径 谢谢, 亚历克斯 回答1 诸如$ {workspace_loc}和$ {project_loc}之类的Eclipse变量仅适用于运行时Eclipse工作区中实际存在的事物。 当您说将它们放在文件系统中的工作区下时,您是否真的将文件导入Eclipse(使用新的Project;或在现有项目中创建链接的文件夹)? 如果文件存在于文件系统中,但不存在于Eclipse本身中,那么Eclipse将只能使用绝对路径访问它们。 顺便说一句,CDT具有自己的变量:$ {WorkspaceDirPath} $ {ProjDirPath} $ {ProjName},它们可以扩展到特定的文件系统位置。 回答2 我不确定CDT构建设置的路径(不在我的计算机上),但是您不能使用工作区变量吗? 类似于:$ {workspace_loc} / boost_1_39_9 编辑:好的
  • Maven:包括在公共存储库中找不到的jar(Maven: Including jar not found in public repository)
    问题 如果我要使用不在Maven公共存储库中的第3方库,那么将其作为对我的项目的依赖关系的最佳方法是什么,以便当其他人签出我的代码时仍然可以构建它? IE 我的应用程序“ A”依赖于公共存储库中不存在的jar“ B”。 但是,我希望将“ B”作为从属关系添加到“ A”,以便当世界另一端的人可以检出代码并仍然能够构建“ A”时 回答1 您可以自己安装项目。 或者,您可以使用如下所示的system范围: <dependency> <groupId>org.group.project</groupId> <artifactId>Project</artifactId> <version>1.0.0</version> <scope>system</scope> <systemPath>${basedir}/lib/project-1.0.0.jar</systemPath> </dependency> systemPath需要项目的绝对路径。 为了简化操作,如果jar文件位于存储库/项目中,则可以使用${basedir}属性,该属性绑定到项目的根目录。 回答2 如果您的父项目带有处于这种情况的模块(需要一个不在存储库中的依赖项),则可以将您的父项目设置为使用exec-maven-plugin插件自动安装您的依赖文件。 例如,我必须使用authorize.net jar文件执行此操作
  • 版本控制中的项目结构(Structure of Projects in Version Control)
    问题 我知道在版本控制中至少有10种不同的方法来构造项目。 我很好奇正在使用的某些方法以及哪种方法对您有用。 我曾经使用SVN,TFS和当前/不幸的是VSS。 我已经看到版本控制的执行效果很差,虽然还可以,但是从来没有很好。 只是为了使事情顺利进行,这里是对我所见过的事情的回顾。 该示例基于SVN,但适用于大多数VCS(不适用于分布式版本控制)。 分支属于站点/ division / web / projectName / vb / src / [trunk | branches | tags]的各个项目分支整个站点,就我所见的情况而言,除了核心组件之外,整个站点都是分支的。 / div // [trunk | branch | tags] / web / projectName / vb / src / 使用main-line作为默认选项,只有在必要时才进行巨大更改。 回答1 我们使用Java进行高度组件化的开发,在主干中有大约250个具有独立生命周期的模块。 依赖关系是通过Maven管理的(这是最佳实践),每次(每两周一次)主动开发的模块都会使用新版本进行标记。 具有严格语义的3位版本号(major.minor.build-重大更改表示向后不兼容,较小更改表示向后兼容,而内部版本号更改表示向后和向前兼容)。 我们最终的软件产品是一个装配体,该装配体引入了数十个单独的模块
  • Transitive Library dependencies are not found in the application
    Say I have a library module which contains some 3rd party libraries like OkHttp. When I include this library in my application I was unable to use these 3rd party libraries. I read the following articles Article 1, Article 2 and tried 1. compile project(':library-name') {after importing the .aar file(of library) as a module into myproject} 2. I included the .aar file in libs folder and added following dependencies build.gradle(project level) allprojects { repositories { flatDir { dirs 'libs' } } } build.gradle(application level) compile fileTree(dir: 'libs', include: ['*.jar']) compile ('com
  • Referencing 3rd party Libraries using *relative* paths in Eclipse-CDT
    what is the best practice to reference 3rd party C++ components (e.g. includes, libraries) using relative paths in Eclipse-CDT? I'm trying to reference Boost and Google protobuf. I've put them each in a folder in my workspace, e.g. /home/user/workspace/boost_1_39_9 I've added a reference to that folder under build settings in the project properties, BUT eclipse won't let me specify that path as relative to the workspace folder, I have to choose it using filesystem and specify an absolute path thanks, Alex
  • 在源代码管理中存储第三方库(Storing third-party libraries in source control)
    问题 应用程序所依赖的库是否应该存储在源代码管理中? 我的一部分说应该,另一部分说不。 添加一个20mb的库使整个应用程序相形见feel是错误的,这仅仅是因为您依赖于它的几个功能(尽管相当繁重)。 您是否应该仅存储jar / dll或什至是项目的分布式zip / tar? 别人在做什么? 回答1 除了在存储库中拥有第三方库之外,值得这样做的方式还可以使其易于跟踪和合并,以便将来轻松地对该库进行更新(例如,安全修复程序等)。 如果您使用Subversion,则使用适当的供应商分支是值得的。 如果您知道在修改第三方代码之前会是阴冷的一天,那么(如@Matt Sheppard所说)外部方法是有道理的,它为您带来了额外的好处,即可以很容易地切换到如果需要安全更新或必备的新功能,则应使用该库的最新版本。 另外,在更新代码库时,如果需要,可以省去长时间的缓慢加载过程,从而跳过外部。 @Stu Thompson提到了在源代码管理中存储文档等。 在较大的项目中,我已经将整个“客户”文件夹存储在源代码管理中,包括发票/账单/会议记录/技术规格等。整个射击比赛。 虽然,请记住将这些内容存储在一个单独的存储库中,该存储库将提供给您:其他开发人员; 客户端; 您的“浏览器源代码视图” ...咳嗽... :) 回答2 存储从现在起10年后构建项目所需的一切。我存储所有库的整个zip发行版,以防万¸
  • Maven生成具有不同/过滤类的多个jar的最佳实践?(Maven best practice for generating multiple jars with different/filtered classes?)
    问题 我开发了一个Java实用程序库(类似于Apache Commons),可在各种项目中使用。 除了胖客户端,我还将它用于移动客户端(具有J9 Foundation概要文件的PDA)。 随着时间的流逝,从一个项目开始的库就分布在多个包中。 结果,我最终获得了很多功能,而并不是所有项目中真正需要的功能。 由于此库还在某些移动/ PDA项目中使用,因此我需要一种方法来仅收集使用的类并生成实际的专用jar。 当前,在使用该库的项目中,我有Ant jar任务,这些任务会(从实用程序项目中)生成专用的jar文件(例如:my-util-1.0-pda.jar,my-util-1.0-rcp.jar)使用包含/排除jar任务功能。 对于移动项目,由于生成的jar文件的大小限制,通常需要这样做。 现在迁移到Maven,我只是想知道是否有最佳实践可以达到类似目的。 我考虑以下情况: [1] -除了主jar工件( my-lib-1.0.jar )之外,还在my-lib项目内部使用分类器(例如: my-lib-1.0-pda.jar )使用Maven Jar插件生成单独的/专用的工件。或Maven组件插件过滤/包含。 我对这种方法不太满意,因为它会因库使用者的需求(过滤器)而污染库。 [2] -为所有专门的客户端/项目创建其他Maven项目,这些项目将“包装”“ my-lib”并生成过滤的jar工件
  • 如何在Eclipse中的第三方库中设置断点?(How to set a breakpoint in Eclipse in a third party library?)
    问题 我从第3方库中获得Class中的NullPointerException。 现在,我想调试整个过程,我需要知道该类是从哪个对象持有的。 但在我看来,我无法在第三方的班级中设置断点。 有人知道我摆脱困境的方法吗? 当然,我使用Eclipse作为我的IDE。 更新:该库是开源的。 回答1 最可靠的方法(最终得到有用的东西)是下载源代码(您说它是开源的),并设置另一个指向该源代码的“ Java项目”。 为此,请下载源并将其解压缩到系统上的某个位置。 单击“文件”->“新建”->“ Java项目”。 在下一个对话框中,为其指定一个项目名称,然后选择“从现有源创建项目”。 浏览到开源库的根目录。 假设该项目所需的所有其他库都包括在您下载的项目中,那么Eclipse将解决所有问题并为您设置构建路径。 您需要从项目的构建路径中删除开源jar,然后将此新项目添加到项目的构建路径中。 现在,您可以将其视为您的代码,然后随意进行调试。 使用其他方法可以解决至少两个问题: 您可以将源文件“附加”到jar文件,但是如果jar文件在编译时没有调试信息,则仍然无法使用。 如果jar文件是使用调试信息编译的( lines,source,vars ...请参见http://java.sun.com/j2se/1.3/docs/tooldocs/win32/javac.html和-g选项)。 您可以添加一个
  • 用于安装多个 3rd 方商业库的 Maven POM 文件(Maven POM file for installing multiple 3rd party commercial libraries)
    问题 我有一堆项目依赖于一组商业 3rd 方库。 我们目前没有公司存储库,所以我必须在我自己的本地存储库中安装这些库。 为每个文件运行mvn install:installFile -Dpackaging=jar -Dfile=<file> -DgroupId=<groupId> -DartifactId=<artifactId> -Dversion=<version>相当乏味。 可以创建一个bat文件,但是有没有办法使用maven来做到这一点? 我正在考虑为所有 jars 和一个包含所有组 ID、工件 ID、版本和文件名的单个 pom 文件创建一个项目,然后可以在该项目中运行mvn install或类似的东西。 这样的事情有可能吗? 注意:我使用的是 Maven 3,但兼容 Maven 2 的解决方案也不错。 回答1 您可以通过多次执行 Maven 安装插件的 install-file 目标来创建 pom.xml。 假设这些文件已经在本地某处可用(或者您可以使用 Wagon 插件下载它们)。 <project> <modelVersion>4.0.0</modelVersion> <groupId>org.somegroup</groupId> <artifactId>my-project</artifactId> <version>1.0</version> <build>
  • Where to put 3rd party libs when using Maven with Tomcat?
    I'm a new to Maven and I didn't find the proper answer to the following problem. For example I have libraries that my project depends on like: log4j, connector j, servlet api, junit, struts etc. When I'm using just Tomcat I can put this jars to %CATALINA_HOME%\lib folder and use them. But as Maven comes in I can configure pom.xml for all dependencies and their scopes. If I do it - can I remove libs from %CATALINA_HOME%\lib folder ? If I can then how Tomcat knows where to find this 3rd party jars ? And Is it a good practice just to have tomcat-native libs (tomcat-util, tomcat-juli, jasper etc)