META-INF/MANIFEST.MF文件中Sealed头的作用与含义

转载 2012年03月21日 12:23:04

转载自: http://zydky.iteye.com/blog/559124

    政府某部门想打造一个国产软件平台,从硬件服务器、操作系统、数据库、应用服务器中间件等全部采用国产平台,并将一个运行良好的应用软件进行改造,以适应国产数据库与原Oracle数据库在SQL语句、系统函数等方面的不同。 

    apusic应用服务器作为国产应用服务器中间件参与了移植测试和压力测试工作。首先跟应用软件开发商基于oracle数据库做了移植测试,从weblogic平台移植到了apusic应用服务器,实现apusic + oracle运行正常。 

    然后跟国产数据库做移植测试,国产数据库采用gbase。应用软件用到了hibernate2作为数据持久工具,由于hibernate没有内置对gbase的dialect支持,gbase厂商自己写了一个类,命名为net.sf.hibernate.dialect.GBaseDialect,并打包成gbase_dialect.jar,放到了应用软件的lib文件夹下。 

    然后启动apusic应用服务器时报错: 

Java代码  收藏代码
  1. net.sf.hibernate.MappingException: could not instantiate id generator  
  2.         at net.sf.hibernate.id.IdentifierGeneratorFactory.create(IdentifierGeneratorFactory.java:82)  
  3.         at net.sf.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:82)  
  4.         at net.sf.hibernate.persister.AbstractEntityPersister.<init>(AbstractEntityPersister.java:630)  
  5.         at net.sf.hibernate.persister.EntityPersister.<init>(EntityPersister.java:716)  
  6.         at net.sf.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:42)  
  7.         at net.sf.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:137)  
  8.         at net.sf.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:768)  
  9.         at com.lbs.commons.op.HibernateSession.currentSession(HibernateSession.java:32)  
  10.         at com.lbs.commons.op.OPManager.query(OPManager.java:159)  
  11.         at com.lbs.cp.plugin.CodeListPlugIn.init(CodeListPlugIn.java:59)  
  12.         at org.apache.struts.action.ActionServlet.initModulePlugIns(ActionServlet.java:1158)  
  13.         at org.apache.struts.action.ActionServlet.init(ActionServlet.java:473)  
  14.         at javax.servlet.GenericServlet.init(GenericServlet.java:215)  
  15.         at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1053)  
  16.         at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:955)  
  17.         at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4035)  
  18.         at org.apache.catalina.core.StandardContext.start(StandardContext.java:4338)  
  19.         at com.cvicse.inforsuite.webContainer.GeronimoStandardContext.access$201(GeronimoStandardContext.java:60)  
  20.         at com.cvicse.inforsuite.webContainer.GeronimoStandardContext$SystemMethodValve.invoke(GeronimoStandardContext.java:343)  
  21.   
  22. ……//此处略去部分异常信息  
  23.   
  24. Caused by: net.sf.hibernate.MappingException: Dialect does not support sequences  
  25.         at net.sf.hibernate.dialect.Dialect.getSequenceNextValString(Dialect.java:319)  
  26.         at net.sf.hibernate.id.SequenceGenerator.configure(SequenceGenerator.java:62)  
  27.         at net.sf.hibernate.id.IdentifierGeneratorFactory.create(IdentifierGeneratorFactory.java:78)  
  28.         ... 83 more  


    貌似是Dialect不支持sequences(getSequenceNextValString()),可是gbase厂商提供的类里有对序列的支持。 

    后来在测试中发现,即使从应用的lib中删除gbase的gbase_dialect.jar,仍然报同样的错误,说明这个jar根本没有加载。 

    由于gbase的gbase_dialect.jar中,GBaseDialect类所在的包为net.sf.hibernate.dialect,跟hibernate提供的其他数据库的dialect包名一致,所以将gbase提供的GBaseDialect类打包在了hibernate2.jar中,跟hibernate提供的其他数据库的dialect在一个jar中,删除gbase_dialect.jar,这时启动apusic正常。 

    据此判断,net.sf.hibernate.dialect.GBaseDialect类文件本身没有问题,gbase提供的gbase_dialect.jar中,除了这个类文件外,就只有META-INF下MANIFEST.MF文件,所以怀疑是这个文件有问题。打开这个文件,只有两行内容: 

Manifest-Version: 1.0 
Sealed:true 

    将gbase_dialect.jar中META-INF下MANIFEST.MF文件Sealed:true去掉,重新打包,放到应用lib下,将先前打包进hibernate2.jar的GBaseDialect类删除,重启apusic,终于正常。 

    到网上搜索关于Sealed:true,找到如下资料: 

引用
包密封 
密封 JAR 文件中的一个包意味着在这个包中定义的所有类都必须在同一个 JAR 文件中找到。这使包的作者可以增强打包类之间的版本一致性。密封还提供了防止代码篡改的手段。 
要密封包,需要在 JAR 的 manifest 文件中为包添加一个 Name 头,然后加上值为“true”的 Sealed 头。与可执行的 JAR 一样,可以在创建 JAR 时,通过指定一个具有适当头元素的 manifest 文件密封一个 JAR,如下所示: 
Name: com/samplePackage/ 
Sealed: true 

Name 头标识出包的相对路径名。它以一个“/”结束以与文件名区别。在 Name 头后面第一个空行之前的所有头都作用于在 Name 头中指定的文件或者包。在上述例子中,因为 Sealed 头出现在 Name 头后并且中间没有空行,所以 Sealed 头将被解释为只应用到包 com/samplePackage 上。 
如果试图从密封包所在的 JAR 文件以外的其他地方装载密封包中的一个类,那么 JVM 将抛出一个 SecurityException 。


    以下是对照这个问题的个人理解,如有谬误,欢迎拍砖: 

    在打包jar时声明Sealed: true,主要目的是防止不同版本之间的jar之间互相调用类,从而导致不可预知的问题,比如在应用下如果有两个hibernate的jar,分别是hibernate2.jar、hibernaet2_1.jar,明显两个版本不一致,打包时声明Sealed: true,则hiberante2.jar里的类只能装载调用本Jar文件里的其他类,而不能调用hibernate2_1.jar里的其他类。 

    gbase打包时包名与Hibernate提供的dialect包名均为net.sf.hibernate.dialect,且声明Sealed: true,JVM会认为所有在net.sf.hibernate.dialect包中的文件都应该在同一个jar下,hibernate2.jar中的类不会去调用gbase_dialect.jar下的文件,找不到net.sf.hibernate.dialect.GBaseDialect类的情况下,JVM使用hibernate提供的默认的GenericDialect,这个类继承自abstract类Dialect,Dialect提供的getSequenceNextValString()方法,默认实现是: 

Java代码  收藏代码
  1. public String getSequenceNextValString(String sequenceName)  
  2.     throws MappingException  
  3.   {  
  4.     throw new MappingException("Dialect does not support sequences");  
  5.   }  


    将gbase打包时Sealed: true去掉,则JVM可以顺利找到gbase的net.sf.hibernate.dialect.GBaseDialect。

Java中 Package Sealing 的探秘之旅

简介         如果没有JAR (Java Archive)的存在,Java也许不至于像今天这样大行天下。JAR 是一个将其他文件或JAR捆绑在一起,并以.jar做为扩展名的文件。它使用与Zi...
  • TechNerd
  • TechNerd
  • 2013年05月19日 21:11
  • 4188

META-INF/MANIFEST.MF 文件

一、前言                                         通过执行形如 jar -cvf src.jar src 命令将多个.class文件打包成JAR包...
  • tianchang042
  • tianchang042
  • 2017年06月03日 23:47
  • 389

C#-sealed 封装类的使用

示例1 : using System; using System.Collections.Generic; using System.Linq; using System.Text; namesp...
  • makenothing
  • makenothing
  • 2014年04月10日 21:22
  • 1321

scala中sealed关键字使用指南

1. 防止继承滥用​sealed关键字可以修饰类和特质(特质)。密封类提供了一种约束:不能在类定义的文件之外定义任何新的子类。然而,这样做有什么用呢?在scala源码中List的实现用到了sealed...
  • ZCF1002797280
  • ZCF1002797280
  • 2016年03月10日 17:22
  • 2505

c# sealed修饰符

sealed的中文意思是密封,故名思义,就是由它修饰的类或方法将不能被继承或是重写。 sealed关键字: 在类声明中使用sealed可防止其它类继承此类;在方法声明中使用sealed修饰符可防止...
  • GAMEloft9
  • GAMEloft9
  • 2015年06月13日 17:15
  • 955

编辑器对C++ 11 特性的支持情况

此文章由人工翻译。 将光标移到文章的句子上,以查看原文。 更多信息。 译文 原文 支持 C++11/14/17 功能(现代 C++) Visual ...
  • huapenguag
  • huapenguag
  • 2016年03月06日 12:25
  • 667

sealed关键字

sealed的中文意思是密封,就是由它修饰的类或方法将不能被继承或是重写。           sealed关键字的作用: 1、在类声明中使用sealed可防止其它类继承此类;在方法声明中使用sea...
  • haobaworenle
  • haobaworenle
  • 2017年06月02日 15:02
  • 202

sealed修饰符

原文地址:http://kb.cnblogs.com/page/42055/ 6.sealed 修饰符是干什么的? 答: sealed 修饰符表示密封用于类时,表示该类不...
  • zr459927180
  • zr459927180
  • 2016年03月22日 14:45
  • 239

面试题28:不能被继承的类

在C#中定义了关键字sealed,被sealed修饰的类不能够被继承。在Java中同样也有关键字final表示一个类不能被继承。C++11提供final关键字使得类不能够被继承。那么,如何自己实现一个...
  • iFuMI
  • iFuMI
  • 2017年06月13日 22:24
  • 356

sealed 修饰符是干什么的?

6.sealed 修饰符是干什么的? 答: sealed 修饰符表示密封用于类时,表示该类不能再被继承,不能和 abstract 同时使用,因为这两个修饰符在含义上互相排斥用于方法和属性时...
  • qwlovedzm
  • qwlovedzm
  • 2013年01月24日 17:43
  • 426
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:META-INF/MANIFEST.MF文件中Sealed头的作用与含义
举报原因:
原因补充:

(最多只允许输入30个字)