java读取tomcat_java-如何读取在Apache Tomcat中运行的Web应用程序的清单文件?

java-如何读取在Apache Tomcat中运行的Web应用程序的清单文件?

我有一个包含清单文件的webapp,在执行蚂蚁构建任务时,我在其中写入应用程序的当前版本。 清单文件创建正确,但是在运行时尝试读取清单文件时,会出现一些奇怪的副作用。 我在清单中读取的代码是这样的:

InputStream manifestStream = Thread.currentThread()

.getContextClassLoader()

.getResourceAsStream("META-INFFFF/MANIFEST.MF");

try {

Manifest manifest = new Manifest(manifestStream);

Attributes attributes = manifest.getMainAttributes();

String impVersion = attributes.getValue("Implementation-Version");

mVersionString = impVersion;

}

catch(IOException ex) {

logger.warn("Error while reading version: " + ex.getMessage());

}

当我将eclipse附加到tomcat时,我看到上面的代码可以工作,但是似乎得到的清单文件与我期望的不同,我可以说出来,因为ant版本和构建时间戳都不同。 然后,将“ META-INFFFF”放入其中,上面的代码仍然有效! 这意味着我正在阅读其他清单,而不是我的清单。 我也试过

this.getClass().getClassLoader().getResourceAsStream(...)

但是结果是一样的。 从tomcat中运行的Webapp内部读取清单文件的正确方法是什么?

编辑:谢谢到目前为止的建议。 另外,我应该注意,我正在独立运行tomcat。 我从命令行启动它,然后将其附加到Eclipse调试器中正在运行的实例。 那不应该有所作为吗?

7个解决方案

89 votes

也许您的副作用来自几乎所有罐子都包含MANIFEST.MF的事实,而您没有得到正确的罐子。 要从Web应用程序读取MANIFEST.MF,我会说:

ServletContext application = getServletConfig().getServletContext();

InputStream inputStream = application.getResourceAsStream("/META-INF/MANIFEST.MF");

Manifest manifest = new Manifest(inputStream);

请注意,由于Eclipse与类加载器一起运行,因此从Eclipse运行Tomcat不同于单独运行Tomcat。

Pascal Thivent answered 2020-06-29T20:37:45Z

11 votes

有点晚了,但这对我有用(Glassfish中的网络应用)

Properties prop = new Properties();

prop.load(getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF"));

System.out.println("All attributes:" + prop.stringPropertyNames());

System.out.println(prop.getProperty("{whatever attribute you want}"));

javadude answered 2020-06-29T20:38:05Z

3 votes

尝试使用jcabi-manifests,它会为您完成所有加载工作。 例如:

String version = Manifests.read("My-Version");

从可用的MANIFEST.MF文件之一中加载My-Version属性。

重要的是要提到(在这里有更多详细信息),在大多数Web容器中,当前的线程类加载器与servlet上下文类加载器不同。 这就是为什么您应该在运行时将servlet上下文附加到寄存器中(更多信息):

Manifests.append(servletContext);

另外,请查看以下内容:[http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html]

yegor256 answered 2020-06-29T20:38:38Z

2 votes

类加载器的默认工作方式是在尝试查找自己的资源之前,将其推迟到父级。 因此,如果父类加载器有可用的清单,那么您将获得此清单。 实际上,应用服务器不一定要这样做,以允许应用覆盖库的版本。 此外,类加载器可以具有多个jar,因此可以具有多个清单。

它可能能够获取您唯一命名的资源之一的资源URL。 打开一个连接。 投射到ServletContext。获取JarFile。从中加载清单。 这可能行不通,特别是如果Tomcat爆发战争。

[更新]当然,war文件本身不在类路径中。 类路径将具有类似WEB-INF / lib /(。jar | .zip)和WEB-INF / classes /的名称。 从ServletContext获取资源应该可以。

最佳解决方案:做一些不同的事情。 :)

Tom Hawtin - tackline answered 2020-06-29T20:39:13Z

2 votes

正确的清单存在于服务器的应用程序根目录中。找出应用程序的根目录,例如通过找出您的类的类路径:

String rootPath = getClass().getProtectionDomain().getCodeSource().getLocation().getPath()

然后将以上路径替换为已建立的路径:Glassfish示例:

/applications//META-INF/MANIFEST.MF

它对我有用。

user3687374 answered 2020-06-29T20:39:41Z

1 votes

不知道读取它的“官方”方式,但是如果MANIFEST.MF无法正确地作为资源加载,那么如何尝试从某个Web路径上的“ ServletContext.getRealPath()”派生其路径呢? 在您的应用中定义?

我还想到了在构建过程中通过ant将应用程序版本也写到其他人的位置(WEB-INF / classes中的属性文件)。

david a. answered 2020-06-29T20:40:06Z

0 votes

这是我将各种版本打印到日志文件的工作。 我已经硬编码了扩展路径,但应用程序可能会使用servletContext.getRealPath("/")来读取webapp文件夹的完整路径。 可能只打印给定的库或lib文件夹中的所有内容。

// print library versions (jersey-common.jar, jackson-core-2.6.1.jar)

try {

List jars = Arrays.asList( "jersey-common", "jackson-core", "openjpa", "mylib" );

StringBuilder verbuf = new StringBuilder();

for(File file : new File("/opt/tomcat/webapps/myapp/WEB-INF/lib/").listFiles() ) {

String name = file.getName();

if (file.isDirectory() || !file.isFile() || !name.endsWith(".jar") ) continue;

name = name.substring(0, name.length()-4);

boolean found = jars.contains(name);

if (!found) {

int idx = name.lastIndexOf('-');

if (idx>0)

found = jars.contains( name.substring(0, idx) );

}

if (!found) continue;

JarFile jarFile = new JarFile(file, false);

try {

String ver;

Manifest mf = jarFile.getManifest();

if (mf!=null) {

ver = mf.getMainAttributes().getValue("Bundle-Version");

if (ver==null || ver.isEmpty())

ver = mf.getMainAttributes().getValue("Implementation-Version");

} else ver=null;

if (verbuf.length()>0) verbuf.append(", ");

verbuf.append(name + "=" + (ver!=null?ver:"") );

} finally {

jarFile.close();

}

}

System.out.println( verbuf.toString() );

} catch(Exception ex) {

ex.printStackTrace();

}

Whome answered 2020-06-29T20:40:26Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值