This discussion is archived
14 Replies Latest reply: Sep 9, 2010 8:28 PM by 712739 RSS

Problem persisting a @Persistent class

788289 Newbie
Currently Being Moderated
I am getting an error saying that
Class com.sleepycat.persist.impl.ReflectionAccessor can not access a member of class FooBarBar with modifiers "public" UNEXPECTED_EXCEPTION: Unexpected internal Exception, may have side effects.
However, class FooBarBar doesn't have any public fields (a super-class has a private field, which is marked @NotPersistent)
This is roughly the class hierarchy for class FooBarBar
@Persistent
class Foo {

     @NotPersistent
     private ANonEntityNonPersistentClass field1 = null;
     
     public ANonEntityNonPersistentClass getField1(){
          if (field1==null){
               someStaticMethod.getInstance();
          }
     }
}

@Persistent
public class FooBar
     extends Foo{
     
     // NO fields
     
     public FooBar{
          super();
     }

               // some public methods
}

@Persistent
public class FooBarBar
     extends FooBar{
     
     // NO fields
     
     public FooBarBar{
          super();
     }
// some public methods
}
  • 1. Re: Problem persisting a @Persistent class
    788289 Newbie
    Currently Being Moderated
    Sorry -- hit "send" too soon

    I am using BDB je 4.0.103

    Would appreciate any help/suggestions

    thanks
  • 2. Re: Problem persisting a @Persistent class
    712739 Newbie
    Currently Being Moderated
    Hi, Sheila,

    I cannot reproduce such error in my sandbox using your class hierarchy.

    So, can you provide more information about this error, including:
    1. The whole and exact error messages or exception messages, not just a sentence you posted before;
    2. How you want to persist the @Persistent class FooBarBar. I have tried two ways, one is using FooBarBar class as a member of an @Entity class, one is let an @Entity class extend from FooBarBar class. Then I persist this @Entity class, and no any error.

    After you provide more information, I will do futher investigation.

    Thanks.

    Eric
    Berkeley DB, Java Edition
    Oracle
  • 3. Re: Problem persisting a @Persistent class
    788289 Newbie
    Currently Being Moderated
    Eric,

    Here is the complete message:
    failed to execute identifier
    org.jhove2.core.JHOVE2Exception: failed to execute identifier
         at org.jhove2.module.identify.IdentifierCommand.execute(IdentifierCommand.java:121)
         at org.jhove2.core.JHOVE2.characterize(JHOVE2.java:180)
         at org.jhove2.app.JHOVE2CommandLine.main(JHOVE2CommandLine.java:179)
    Caused by: org.jhove2.core.JHOVE2Exception: Could not persist Module
         at org.jhove2.persist.berkeleydpl.BerkeleyDbBaseModuleAccessor.persistModule(BerkeleyDbBaseModuleAccessor.java:40)
         at org.jhove2.persist.berkeleydpl.BerkeleyDbSourceAccessor.addModule(BerkeleyDbSourceAccessor.java:110)
         at org.jhove2.core.source.AbstractSource.addModule(AbstractSource.java:219)
         at org.jhove2.module.identify.IdentifierCommand.execute(IdentifierCommand.java:107)
         ... 2 more
    Caused by: com.sleepycat.je.EnvironmentFailureException: (JE 4.0.103) java.lang.IllegalAccessException: Class com.sleepycat.persist.impl.ReflectionAccessor can not access a member of class org.jhove2.persist.berkeleydpl.BerkeleyDbIdentifierAccessor with modifiers "public" UNEXPECTED_EXCEPTION: Unexpected internal Exception, may have side effects.
         at com.sleepycat.je.EnvironmentFailureException.unexpectedException(EnvironmentFailureException.java:286)
         at com.sleepycat.compat.DbCompat.unexpectedException(DbCompat.java:500)
         at com.sleepycat.persist.impl.ReflectionAccessor.newInstance(ReflectionAccessor.java:153)
         at com.sleepycat.persist.impl.ComplexFormat.newInstance(ComplexFormat.java:513)
         at com.sleepycat.persist.impl.RecordInput.readObject(RecordInput.java:174)
         at com.sleepycat.persist.impl.ReflectionAccessor$ObjectAccess.read(ReflectionAccessor.java:406)
         at com.sleepycat.persist.impl.ReflectionAccessor.readNonKeyFields(ReflectionAccessor.java:285)
         at com.sleepycat.persist.impl.ReflectionAccessor.readNonKeyFields(ReflectionAccessor.java:273)
         at com.sleepycat.persist.impl.ComplexFormat.readObject(ComplexFormat.java:520)
         at com.sleepycat.persist.impl.PersistEntityBinding.readEntity(PersistEntityBinding.java:101)
         at com.sleepycat.persist.impl.PersistEntityBinding.entryToObjectInternal(PersistEntityBinding.java:71)
         at com.sleepycat.persist.impl.PersistEntityBinding.entryToObject(PersistEntityBinding.java:58)
         at com.sleepycat.persist.PrimaryIndex.put(PrimaryIndex.java:387)
         at com.sleepycat.persist.PrimaryIndex.put(PrimaryIndex.java:333)
         at org.jhove2.persist.berkeleydpl.BerkeleyDbBaseModuleAccessor.persistModule(BerkeleyDbBaseModuleAccessor.java:37)
         ... 5 more
    Caused by: java.lang.IllegalAccessException: Class com.sleepycat.persist.impl.ReflectionAccessor can not access a member of class org.jhove2.persist.berkeleydpl.BerkeleyDbIdentifierAccessor with modifiers "public"
         at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
         at java.lang.reflect.Constructor.newInstance(Constructor.java:505)
         at com.sleepycat.persist.impl.ReflectionAccessor.newInstance(ReflectionAccessor.java:151)
         ... 17 more
    Here are the relevant classes/hierarchies
    Interface Source
         AbstractSource (entity class)  primary key Long sourceId;
    
    Interface Module
        Abstractclass AbstractModule (entity class)  primary key Long moduleId; secondary key Long parentSourceId, relate=MANY_TO_ONE, relatedEntity=AbstractSource.class,
                                                                       onRelatedEntityDelete=NULLIFY)     
            IdentiferModule  Concrete class  (persistent class)
               which contains persistent member field of type  BerkeleyDbIdentifierAccessor
     
    
    
     BerkeleyDbIdentifierAccessor is the FooBarBar class of my simplified code in my first message
     
     Interface BerkeleyDbAccessor
          BerkeleyDbBaseAccessor  (persistent class with non-persistent field - uses static method to popuplate from a static singleton) 
                               @NotPersistent
                    private BerkeleyDbPersistenceManager berkeleyDbPersistenceManager = null;      // class that sets up BDB env, store, indexes, registers classes, etc, does data access thru indexes
    
                               public BerkeleyDbPersistenceManager getBerkeleyDbPersistenceManager()
                   throws JHOVE2Exception {
              if (berkeleyDbPersistenceManager == null){
                   berkeleyDbPersistenceManager = 
                        (BerkeleyDbPersistenceManager) PersistenceManagerUtil.getPersistenceManagerFactory().getInstance();
              }
              return berkeleyDbPersistenceManager;
                  }                               
     
          BerkeleyDbBaseModuleAccessor  (persisent class with NO fields) -- contains peristModule() method
     
              public Module persistModule(Module module) throws JHOVE2Exception {
                   if (module != null){
                        try{
                             getBerkeleyDbPersistenceManager().getModuleByModuleId().put((AbstractModule) module);
                        }
                        catch(DatabaseException e){
                             throw new JHOVE2Exception("Could not persist Module" , e);
                        }
                   }
                   return module;
               }
              
           BerkeleyDbIdentifierAccessor persistent class with NO fields -- member field of Identifier Module which is to be persisted
    At the point where the exception is thrown, an IdentifierModule is being added as a child module of a Source (via setting the secondary key field parentSournceId of the IdentifierModule). The IdentifierModule is then persisted when that update to its secondary key field was maide, using the persistModule() method of the BerkeleyDbIdentifierAccessor field of the IdentifierModule itself . This is when the exception is thrown.

    Thanks so much for looking into this.

    Sheila
  • 4. Re: Problem persisting a @Persistent class
    greybird Expert
    Currently Being Moderated
    Sheila, I think we need to see the complete/unmodified source code (not the methods, but at least the fields) for all the persistent classes. Are you nesting classes without the static modifier by chance?

    --mark                                                                                                                                                                                                                                                                                                                                                                                                                                               
  • 5. Re: Problem persisting a @Persistent class
    788289 Newbie
    Currently Being Moderated
    Here are the classes in the BerkeleyDbAccessor hierarchy
    public interface ModuleAccessor {
         /**
          * Persists the Module object (may be no-op, if ModuleAccessor is for in-memory JHOVE2)
          * @param source Module to be persisted
          * @return Module object that was persisted
          * @throws JHOVE2Exception
          */
         public Module persistModule(Module module) throws JHOVE2Exception;
         /**
          * Retrieves persisted Module object dereferenced via a key
          * @param key Object by which persisted Module is dereferenced and retrieved
          * @return Module object corresponding to key
          * @throws JHOVE2Exception
          */
         public Module retrieveModule(Object key) throws JHOVE2Exception;
         
    }
    
    
    public interface BerkeleyDbAccessor {
    
         /**
          * Source and Module accessors are persistent; the Persistence Manager, with all the BerkeleyDB-related fields,
          * cannot be persisted.  Access to the Persistence Manager is via this method, which uses a static
          * utility method to access the BerkeleyDbPersistenceManagerFactory to access its (singleton) instance
          * of the BerkeleyDbPersistenceManager.
          * @return the berkeleyDbPersistenceManager
          */
         public BerkeleyDbPersistenceManager getBerkeleyDbPersistenceManager() 
         throws JHOVE2Exception;
    }
    
    @Persistent
    public class BerkeleyDbBaseAccessor implements BerkeleyDbAccessor {
         @NotPersistent
         private BerkeleyDbPersistenceManager berkeleyDbPersistenceManager = null;
         /* (non-Javadoc)
          * @see org.jhove2.persist.berkeleydpl.BerkeleyDbAccessor#getBerkeleyDbPersistenceManager()
          */
         
         public BerkeleyDbBaseAccessor(){}
         
         @Override
         public BerkeleyDbPersistenceManager getBerkeleyDbPersistenceManager()
                   throws JHOVE2Exception {
              if (berkeleyDbPersistenceManager == null){
                   berkeleyDbPersistenceManager = 
                        (BerkeleyDbPersistenceManager) PersistenceManagerUtil.getPersistenceManagerFactory().getInstance();
              }
              return berkeleyDbPersistenceManager;
         }
    
    }
    @Persistent
    public class BerkeleyDbBaseModuleAccessor 
         extends BerkeleyDbBaseAccessor 
         implements BerkeleyDbAccessor, ModuleAccessor {
    
         /**
          * Constructor
          */
         public BerkeleyDbBaseModuleAccessor(){
              super();
         }
         
         @Override
         public Module persistModule(Module module) throws JHOVE2Exception {
              if (module != null){
                   //When one of the put methods in the PrimaryIndex is called and a new key is assigned, 
                   //the assigned value is returned to the caller via the key field of the entity object that 
                   //is passed as a parameter
                   try{
                        getBerkeleyDbPersistenceManager().getModuleByModuleId().put((AbstractModule) module);
                   }
                   catch(DatabaseException e){
                        throw new JHOVE2Exception("Could not persist Module" , e);
                   }
              }
              return module;
         }
    
         @Override
         public Module retrieveModule(Object key) throws JHOVE2Exception {
              Long longKey = null;
              Module module = null;
              if (key != null && key instanceof Long){
                   try{
                        module = getBerkeleyDbPersistenceManager().getModuleByModuleId().get(longKey);
                   }
                   catch (DatabaseException e){
                        throw new JHOVE2Exception("Could not retrieve module for key" + key.toString(), e);
                   }
              }
              return module;
         }
    }
    
    @Persistent
    class BerkeleyDbIdentifierAccessor extends BerkeleyDbBaseModuleAccessor
    implements IdentifierAccessor {
    
         public BerkeleyDbIdentifierAccessor(){
              super();
         }
         /* (non-Javadoc)
          * @see org.jhove2.persist.IdentifierAccessor#getFileSourceIdentifier(org.jhove2.module.identify.Identifier)
          */
         @Override
         public FileSourceIdentifier getFileSourceIdentifier(Identifier module)
         throws JHOVE2Exception {
              FileSourceIdentifier fsi = null;
              if (module != null){
                   try{
                        Module rModule = 
                             this.getBerkeleyDbPersistenceManager().
                             getFileSourceIdentifierByParentIdentifier().get(module.getModuleId());
                        if (rModule != null){
                             fsi = (FileSourceIdentifier)rModule;
                        }
                   }
                   catch(DatabaseException e){
                        throw new JHOVE2Exception("Unable to retrieve FileSourceIdentifier",e);
                   }
              }
              return fsi;
         }
    Here are the classes in the Module hierarchy (IdentifierModule has BerkeleyDbIdentifierAccessor field, whose persistModule() method is invoked to persist the IdentifierModule,including its BerkeleyDbIdentifierAccessor field)
    public interface Module
         extends Reportable // Reportable is an Interface
    {
         public enum Scope {
              Generic,
              Specific
         }
         @ReportableProperty(order = 4, value = "Module developers.")
         public List<Agent> getDevelopers();
         @ReportableProperty(order = 7, value = "Module informative note.")
         public String getNote();
         @ReportableProperty(order = 2, value = "Module release date.")
         public String getReleaseDate();
         @ReportableProperty(order = 3, value = "Module rights statement.")
         public String getRightsStatement();
         @ReportableProperty(order = 5, value = "Module scope: generic or " +
                   "specific (to a source unit.")
         public Scope getScope();
             @ReportableProperty(order = 8, value = "Timer info for this module.")
             public TimerInfo getTimerInfo();
         @ReportableProperty(order = 1, value = "Module version identifier.")
         public String getVersion();
         @ReportableProperty(order = 6, value = "External product wrapped by the module.")
         public WrappedProduct getWrappedProduct();
         public Long getModuleId();
         public Long getParentSourceId();
         public void setModuleId(Long moduleId);
         public void setParentSourceId(Long parentSourceId);
         public ModuleAccessor getModuleAccessor();
         public void setModuleAccessor(ModuleAccessor moduleAccessor);
    }
    
    @Persistent
    public abstract class AbstractReportable
         implements Reportable
    {
         protected I8R myI8R = null;
         protected String reportableName = null;     
         public AbstractReportable(){};
         @Override
         public I8R getReportableIdentifier() {
              if (this.myI8R == null){
                   this.myI8R = I8R.makeReportableI8R(this);
              }
              return this.myI8R;
         }
         @Override
         @ReportableProperty(value = "Reportable name")
         public String getReportableName(){
              if (this.reportableName == null) {
                   this.reportableName = this.getClass().getSimpleName();
              }
              return reportableName;
         }
         @Override
         public void setReportableName(String name){
              this.reportableName = name;
         }     
    }
    
    
    @Entity
    public abstract class AbstractModule
         extends AbstractReportable
         implements Module 
     {
         @PrimaryKey(sequence="MODULE_ID")
         protected Long moduleId;
         
         @SecondaryKey(relate=MANY_TO_ONE, relatedEntity=AbstractSource.class,
                   onRelatedEntityDelete=NULLIFY)               
         protected Long parentSourceId;
         
         protected ModuleAccessor moduleAccessor;
              
    
         protected List<Agent> developers;
         protected String name;
         protected String note;
         protected String releaseDate;
         protected String rights;
         protected Scope scope;
         protected String version;
         protected WrappedProduct wrappedProduct;
         protected TimerInfo timerInfo;
         
         public AbstractModule(String version, String release, String rights,
                                 Scope scope, ModuleAccessor moduleAccessor)
         {     
              super();
              this.version     = version;
              this.releaseDate = release;
              this.rights      = rights;
              this.scope        = scope;
              
              this.developers  = new ArrayList<Agent>();          
              this.timerInfo   = new TimerInfo();
              this.name        = this.getClass().getSimpleName();
              this.moduleAccessor = moduleAccessor;
         }
    
         public AbstractModule(){
              super();
         }
    
         @Override
         public List<Agent> getDevelopers() {
              return this.developers;
         }
    
         @Override
         public String getNote() {
              return this.note;
         }
    
         @Override
         public String getReleaseDate() {
              return this.releaseDate;
         }
    
         @Override
         public String getRightsStatement() {
              return this.rights;
         }
         @Override
         public Scope getScope() {
              return this.scope;
         }
    
         @Override
         public String getVersion() {
              return this.version;
         }
    
         public void setDevelopers(List<Agent> developers) {
              this.developers = developers;
         }
    
         public void setNote(String note) {
              this.note = note;
         }
         
         @Override
         public WrappedProduct getWrappedProduct() {
              return this.wrappedProduct;
         }
         
         public void setWrappedProduct(WrappedProduct product) {
              this.wrappedProduct = product;
         }
         
         /** Get module timer information.
          * @return Module timer information
          */
         @Override
         public TimerInfo getTimerInfo() {
              return timerInfo;
         }
         @Override
         public Long getModuleId() {
              return moduleId;
         }
         @Override
         public Long getParentSourceId() {
              return parentSourceId;
         }
         @Override
         public void setModuleId(Long moduleId) {
              this.moduleId = moduleId;
         }
         @Override
         public void setParentSourceId(Long parentSourceId) {
              this.parentSourceId = parentSourceId;
         }
         @Override
         public ModuleAccessor getModuleAccessor() {
              return moduleAccessor;
         }
         @Override
         public void setModuleAccessor(ModuleAccessor moduleAccessor) {
              this.moduleAccessor = moduleAccessor;
         }
    }
    public interface Identifier
         extends Module
    {
         public Set<FormatIdentification> identify(JHOVE2 jhove2, Source source)
                   throws IOException, JHOVE2Exception;
         public FileSourceIdentifier getFileSourceIdentifier() throws JHOVE2Exception;
    
         public FileSourceIdentifier setFileSourceIdentifier(FileSourceIdentifier fileSourceIdentifier) throws JHOVE2Exception;
    
    }
    @Persistent
    public class IdentifierModule
         extends AbstractModule 
         implements Identifier
    {
         public static final String VERSION = "2.0.0";
         public static final String RELEASE = "2010-09-10";
         public static final String RIGHTS = "Copyright 2010 by The Regents of the University of California, "
              + "Ithaka Harbors, Inc., and The Board of Trustees of the Leland "
              + "Stanford Junior University. "
              + "Available under the terms of the BSD license.";
    
         public IdentifierModule() {
              super(VERSION, RELEASE, RIGHTS, Scope.Generic, null);
         }
    
    
         public IdentifierModule(IdentifierAccessor identifierAccessor) {
              super(VERSION, RELEASE, RIGHTS, Scope.Generic, identifierAccessor);
         }
    
         @Override
         public Set<FormatIdentification> identify(JHOVE2 jhove2, Source source)
              throws IOException, JHOVE2Exception
         {
              Set<FormatIdentification> presumptiveFormatIDs = 
                   new TreeSet<FormatIdentification>();
              if (source instanceof ClumpSource) {
                   /* ClumpSources are only created when identified as instances
                    * of a particular clump format, so should have identifications
                    * already.
                    */
                   ;
              }
              else if (source instanceof DirectorySource ||
                         source instanceof ZipDirectorySource) {
                   FormatIdentification id =
                        new FormatIdentification(new I8R(I8R.JHOVE2_PREFIX + "/" +
                                                           I8R.JHOVE2_FORMAT_INFIX +
                                                           "/directory"),
                                                  Confidence.PositiveSpecific,
                                                  this.getReportableIdentifier());
                   presumptiveFormatIDs.add(id);
              }
              else if (source instanceof FileSetSource) {
                   FormatIdentification id =
                        new FormatIdentification(new I8R(I8R.JHOVE2_PREFIX + "/" +
                                                           I8R.JHOVE2_FORMAT_INFIX +
                                                           "/file-set"),
                                                  Confidence.PositiveSpecific,
                                                  this.getReportableIdentifier());
                   presumptiveFormatIDs.add(id);
              }
              else {   /* Identify file source unit. */                    
                   TimerInfo timer = this.getFileSourceIdentifier().getTimerInfo();
                   timer.setStartTime();
                   try {
                        Set<FormatIdentification> formats =
                             this.getFileSourceIdentifier().identify(jhove2, source);
                        presumptiveFormatIDs.addAll(formats);
                   }
                   finally {
                        timer.setEndTime();
                   }
              }
              return presumptiveFormatIDs;
         }
    
    
         @Override
         public FileSourceIdentifier getFileSourceIdentifier()  
         throws JHOVE2Exception{
              if (this.getModuleAccessor()==null){
                   throw new JHOVE2Exception("IdentifierAccessor is null");
              }
              IdentifierAccessor ia = (IdentifierAccessor) this.getModuleAccessor();
              return ia.getFileSourceIdentifier(this);
         }
    
         /**
          * Set file source identifier module.
          * @param fileSourceIdentifier File source identifier module
          */
         public FileSourceIdentifier setFileSourceIdentifier(FileSourceIdentifier fileSourceIdentifier)  
         throws JHOVE2Exception{
              if (this.getModuleAccessor()==null){
                   throw new JHOVE2Exception("IdentifierAccessor is null");
              }
              IdentifierAccessor ia = (IdentifierAccessor) this.getModuleAccessor();
              return ia.setFileSourceIdentifier(this, fileSourceIdentifier);
         }
    
    }
    
    public interface FileSourceIdentifier
         extends Module
    {
         public Set<FormatIdentification> identify(JHOVE2 jhove2, Source source)
                   throws IOException, JHOVE2Exception;
    
         public Long getParentIdentifierId();
         public void setParentIdentifierId(Long id);
    }
    More classes in next message -- I'm exeeding themessage length limit

    Many thanks for giving thought to this.

    Sheila
  • 6. Re: Problem persisting a @Persistent class
    788289 Newbie
    Currently Being Moderated
    @Persistent
    public class DROIDIdentifier
         extends AbstractModule
         implements FileSourceIdentifier
    {
    
         public static final String VERSION = "2.0.0";
    
         public static final String RELEASE = "2010-09-10";
    
         public static final String RIGHTS = "Copyright 2010 by The Regents of the University of California, "
              + "Ithaka Harbors, Inc., and The Board of Trustees of the Leland "
              + "Stanford Junior University. "
              + "Available under the terms of the BSD license.";
         
         @SecondaryKey(relate=ONE_TO_ONE, relatedEntity=AbstractModule.class,
                   onRelatedEntityDelete=NULLIFY)
         protected Long parentIdentifierId;
         
         public static final String DROID_NAME = "DROID (Digital Record Object Identification)";
    
         public static final String PUIDMAP_BEANNAME = "DroidMap";
    
         public static final String JHOVE2BEANMAP_BEANNAME = "FormatBeanMap";
    
         protected Message fileNotIdentifiedMessage;  // Message is a persistent class
    
         protected Message fileNotRunMessage;
    
         protected Message fileErrorMessage;
    
         private String configurationFileName = null;
         
         private String signatureFileName = null;
         
    
         @NotPersistent
         private static ConcurrentMap<String, String> puidToJhoveId;
    
         @NotPersistent
         private static ConfigFile cachedConfigFile = null;
    
         @NotPersistent
         private static FFSignatureFile cachedSigFile = null;
    
         /**Instantiate a new <code>DROIDIdentifier</code> module that wraps DROID.
          * @throws JHOVE2Exception 
          */
         public DROIDIdentifier()
              throws JHOVE2Exception
         {
              this(null, null, null);
         }
         
         /**Instantiate a new <code>DROIDIdentifier</code> module that wraps DROID.
          * @param moduleAccessor persistence manager
          * @throws JHOVE2Exception 
          */
         public DROIDIdentifier(ModuleAccessor moduleAccessor)
              throws JHOVE2Exception
         {
              this(null, null, moduleAccessor);
         }
         
         /**Instantiate a new <code>DROIDIdentifier</code> module that wraps DROID.
          * @param configFileName path to DROID configuration file
          * @param sigFileName path to DROID signature file
          * @param moduleAccessor persistence manager
          * @throws JHOVE2Exception 
          */
         public DROIDIdentifier(String configFileName, String sigFileName, 
                   ModuleAccessor moduleAccessor)
              throws JHOVE2Exception
         {
              super(VERSION, RELEASE, RIGHTS, Scope.Generic, moduleAccessor);
              this.setConfigFileName(configFileName);
              this.setSigFileName(sigFileName);
         }
         
         /**
          * Presumptively identify the format of a source unit.
          * 
          * @param jhove2
          *            JHOVE2 framework
          * @param source
          *            Source unit
          * @return Set of presumptive format identifications
          * @throws IOException
          *             I/O exception encountered identifying the source unit
          * @throws JHOVE2Exception
          */
         @Override
         public Set<FormatIdentification> identify(JHOVE2 jhove2, Source source)
              throws IOException, JHOVE2Exception
         {
              DROIDWrapper droid = new DROIDWrapper();
              Set<FormatIdentification> presumptiveFormatIds =
                   new TreeSet<FormatIdentification>();
              try {
                   ConfigFile configFile = getCachedConfigFile(this.getConfigurationFile());
                   FFSignatureFile sigFile = getCachedSignatureFile(configFile, this.getSignatureFile());
                   droid.setConfigFile(configFile);
                   droid.setSigFile(sigFile);
                   IdentificationFile idf = droid.identify(source);
                   boolean matchFound = this.matchFound(idf, jhove2);
                   if (matchFound){
                        String msgText = idf.getWarning();                    
                        Message idWarningMessage = null;
                        if (msgText != null && msgText.length()>0) {
                             Object [] messageParms = new Object []{msgText};
                             idWarningMessage = new Message(Severity.WARNING,
                                       Context.OBJECT,
                                       "org.jhove2.module.identify.DROIDIdentifier.identify.idWarningMessage",
                                       messageParms, jhove2.getConfigInfo());
                        }
                        for (int i=0; i<idf.getNumHits(); i++){          
                             ArrayList<Message> idMessages = new ArrayList<Message>();
                             ArrayList<Message> unmatchedPUIDMessages = 
                                  new ArrayList<Message>();
                             Message hitWarningMsg = null;
                             if (idWarningMessage != null){
                                  idMessages.add(idWarningMessage);
                             }
                             FileFormatHit ffh = idf.getHit(i);
                             String hitWarning = ffh.getHitWarning();
                             if (hitWarning != null && hitWarning.length()>0) {
                                  Object[]messageParms = new Object[]{hitWarning};
                                  hitWarningMsg = new Message(Severity.WARNING,
                                            Context.OBJECT,
                                            "org.jhove2.module.identify.DROIDIdentifier.identify.hitWarningMsg",
                                            messageParms, jhove2.getConfigInfo());
                                  idMessages.add(hitWarningMsg);
                             }
                             FileFormat ff = ffh.getFileFormat();                    
                             String puid = ff.getPUID();
                             I8R droidId = new I8R(puid, I8R.Namespace.PUID);
                             Confidence jhoveConfidence = this.getJHOVE2Confidence(ffh);     
                             // look up the JHOVE2 format id corresponding to DROID format id (PUID)
                             String jhoveFormatId = null;
                             if (! getPUIDtoJ2ID(jhove2).containsKey(puid)){
                                  // if there is no match, attach an ERROR message to the FormatIdentification, 
                                  // and use the default JHOVE2 format
                                  Object[]messageParms = new Object[]{puid};
                                  Message missingPuid = new Message(Severity.ERROR,
                                            Context.PROCESS,
                                            "org.jhove2.module.identify.DROIDIdentifier.identify.missingPUID",
                                            messageParms, jhove2.getConfigInfo());
                                  unmatchedPUIDMessages.add(missingPuid);
                             }
                             else {
                                  jhoveFormatId = getPUIDtoJ2ID(jhove2).get(puid);     
                             }
                             idMessages.addAll(unmatchedPUIDMessages);
                             I8R jhoveId = null;
                             if (jhoveFormatId != null) {
                                  jhoveId = new I8R(jhoveFormatId);
                             }
                             FormatIdentification fi =
                                  new FormatIdentification(jhoveId, jhoveConfidence,
                                                            this.getReportableIdentifier(),
                                                            droidId, idMessages);
                             presumptiveFormatIds.add(fi);                         
                        }
                   }
              }
              catch (IOException e) {
                   throw e;
              }
              catch (Exception ex) {
                   throw new JHOVE2Exception("Failure running DROID " + ex.getMessage(),ex);
              }
              return presumptiveFormatIds;
         }
    
         /**
          * If DROID config file has not yet been parsed, parse and return it;
          * Otherwise simply returns parsed config file
          * @param configFilePath path to DROID config file
          * @return parsed config file object
          * @throws Exception
          */
         private static synchronized ConfigFile getCachedConfigFile(String configFilePath)
              throws Exception
         {
              if (cachedConfigFile == null) {
                   cachedConfigFile = DROIDWrapper.parseConfigFile(configFilePath);
              }
              return cachedConfigFile;
         }
    
         /**
          * If DROID signature file has not yet been parsed, parses and returns it;
          * Otherwise, just returns parsed signature file
          * @param configFile  parsed DROID config file object
          * @param sigFilePath  path to DROID signature file
          * @return parsed signature file contents
          * @throws Exception
          */
         private static synchronized FFSignatureFile getCachedSignatureFile(ConfigFile configFile,
                                                                              String sigFilePath)
              throws Exception
         {
              if (cachedSigFile == null) {
                   cachedSigFile = DROIDWrapper.parseSignatureFile(configFile,
                                                                            sigFilePath);
              }
              return cachedSigFile;
         }
    
        /**
         * Return the name of the configuration file.
         * @return Configuration file name
         */
        public String getConfigurationFileName() {
            return configurationFileName;
        }
    
        /** Get DROID configuration file path.
         * @return DROID configuration file path
         * @throws JHOVE2Exception 
         */
        @ReportableProperty(order = 1, value = "DROID configuration file path.")
        public String getConfigurationFile()
            throws JHOVE2Exception
        {
            String path = FeatureConfigurationUtil.getFilePathFromClasspath(this.getConfigurationFileName(), "DROID config file");
            return path;
        }
    
        /**
         * Get DROID File Not Found message.
         * 
         * @return File Not Found message
         */
        @ReportableProperty(order = 13, value = "DROID File Not Identified Message")
        public Message getFileNotIdentifiedMessage() {
            return this.fileNotIdentifiedMessage;
        }
        
        /**
         * Get DROID File Not run message.
         * 
         * @return File Not run message
         */
        @ReportableProperty(order = 14, value = "DROID File Not Run Message")
        public Message getFileNotRunMessage() {
            return this.fileNotRunMessage;
        }
        
        /**
         * Get DROID File error message.
         * 
         * @return File error message
         */
        @ReportableProperty(order = 15, value = "DROID File Error Message.")
        public Message getFileErrorMessage() {
            return this.fileErrorMessage;
        }
        
        /**
         * Map from DROID confidence levels to JHOVE2 confidence levels
         * @param ffh File format hit containing DROID confidence level
         * @return JHOVE2 confidence level for this identifier
         */
        protected Confidence getJHOVE2Confidence(FileFormatHit ffh) {
            int droidConfidence = ffh.getHitType();
            Confidence jhoveConfidence;
            switch (droidConfidence){
            case JHOVE2IAnalysisController.HIT_TYPE_POSITIVE_SPECIFIC:
                jhoveConfidence = Confidence.PositiveSpecific;
                break;
            case JHOVE2IAnalysisController.HIT_TYPE_POSITIVE_GENERIC_OR_SPECIFIC:
                jhoveConfidence = Confidence.PositiveGeneric;
                break;
            case JHOVE2IAnalysisController.HIT_TYPE_POSITIVE_GENERIC:
                jhoveConfidence = Confidence.PositiveGeneric;
                break;
            case JHOVE2IAnalysisController.HIT_TYPE_TENTATIVE:
                jhoveConfidence = Confidence.Tentative;
                break;
            default:
                jhoveConfidence = Confidence.Negative;
            }   
            return jhoveConfidence;
        }
    
        /**
         * Gets the mapping from DROID PUID to JHOVE2 Format Identifier. 
         * Initializes the static map on first invocation.
         * 
         * @return DROID PUID to JHOVE2 Format Identifier map
         * @throws JHOVE2Exception
         */
        public static ConcurrentMap<String,String> getPUIDtoJ2ID(JHOVE2 jhove2)
            throws JHOVE2Exception
        {
            if (puidToJhoveId == null){
                 puidToJhoveId = jhove2.getConfigInfo().getFormatAliasIdsToJ2Ids(I8R.Namespace.PUID);
            }
            return puidToJhoveId;
        }
     
        /** Get DROID signature file path.
         * @return DROID signature file path
         * @throws JHOVE2Exception 
         */
        @ReportableProperty(order = 2, value = "DROID signature file path.")
        public String getSignatureFile() throws JHOVE2Exception {
            String path = FeatureConfigurationUtil.getFilePathFromClasspath(this.getSignatureFileName(), "DROID signature file");
            return path;
        }
    
        /**
         * Return the name of the signature file
         * @return the signatureFileName
         */
        public String getSignatureFileName() {
            return signatureFileName;
        }
     
         /**
          * Checks DROID file classification codes to see if DROID was able to match file
          * NOTE:  SIDE EFFECTS:  if there are errors, or if no identifier can be made, or
          *                       if DROID returns warning message, this method populates 
          *                       the relevant Message member of this object instance
          * @param idf DROID {@link uk.gov.nationalarchives.droid.IdentificationFile} object
          * @param jhove2 
          * @return true if DROID able to identify file; otherwise false
          * @throws JHOVE2Exception 
          */
         protected boolean matchFound(IdentificationFile idf, JHOVE2 jhove2)
              throws JHOVE2Exception
         {
              boolean matchFound = false;
              int classification = idf.getClassification();
              String msgText = null;
              switch (classification){
              case JHOVE2IAnalysisController.FILE_CLASSIFICATION_NOHIT:
                   msgText = idf.getWarning();
                   if (msgText==null){
                        msgText = new String("");
                   }
                   Object[]messageParms = new Object[]{msgText};
                   this.fileNotIdentifiedMessage = new Message(Severity.WARNING,
                             Context.OBJECT,
                             "org.jhove2.module.identify.DROIDIdentifier.fileNotIdentifiedMessage",
                             messageParms, jhove2.getConfigInfo());
                   break;
              case JHOVE2IAnalysisController.FILE_CLASSIFICATION_NOTCLASSIFIED:
                   msgText = idf.getWarning();
                   if (msgText==null){
                        msgText = new String("");
                   }
                   messageParms = new Object[]{msgText};
                   this.fileNotRunMessage = new Message(Severity.ERROR,
                             Context.PROCESS,
                             "org.jhove2.module.identify.DROIDIdentifier.fileNotRunMessage",
                             messageParms, jhove2.getConfigInfo());
                   break;
              case JHOVE2IAnalysisController.FILE_CLASSIFICATION_ERROR:
                   msgText = idf.getWarning();
                   if (msgText==null){
                        msgText = new String("");
                   }
                   messageParms = new Object[]{msgText};
                   this.fileErrorMessage = new Message(Severity.ERROR,
                             Context.PROCESS,
                             "org.jhove2.module.identify.DROIDIdentifier.fileErrorMessage",
                             messageParms, jhove2.getConfigInfo());
                   break;
              default:
                   matchFound = true;
                   break;
              }// end switch
              return matchFound;
         }
    
    
         /** Set File Error message.
          * @param fileErrorMessage File Error message
          */
         public void setFileErrorMessage(Message fileErrorMessage) {
              this.fileErrorMessage = fileErrorMessage;
         }
         
         /** Set File Not Identified message.
          * @param fileNotIdentifiedMessage File Not Identified message
          */
         public void setFileNotIdentifiedMessage(Message fileNotIdentifiedMessage) {
              this.fileNotIdentifiedMessage = fileNotIdentifiedMessage;
         }
    
         /** Set File Not Run message.
          * @param fileNotRunMessage File Not Run message
          */
         public void setFileNotRunMessage(Message fileNotRunMessage) {
              this.fileNotRunMessage = fileNotRunMessage;
         }
    
         /**
          * Set the name of the config file
          * @param configurationFileName the configurationFileName to set
          */
         public void setConfigFileName(String configFileName) {
              this.configurationFileName = configFileName;
         }
    
         /**
          * Set the name of the signature file
          * @param signatureFileName the signatureFileName to set
          */
         public void setSigFileName(String sigFileName) {
              this.signatureFileName = sigFileName;
         }
    
         @Override
         public Long getParentIdentifierId() {
              return this.parentIdentifierId;
         }
    
         @Override
         public void setParentIdentifierId(Long id) {
              this.parentIdentifierId = id;
         }
    
    
    }
    @Persistent
    public class Message {
         /** Message contexts. */
         public enum Context {
              PROCESS, OBJECT
         }
         /** Message severities. */
         public enum Severity {
              ERROR, WARNING, INFO
         }
         /** Message code. */
         protected String messageCode;
    
         /** Localized Message Text */
         protected String localizedMessageText;
    
         /** Message context. */
         protected Context context;
    
         /** Message severity. */
         protected Severity severity;
    
         /** Message Locale. */
         protected Locale locale;
         
         protected ConfigInfo configInfo;
    
         /** Default Locale */
         private static Locale defaultLocale;
    
              static {
                   defaultLocale = Locale.getDefault();
              }
    
         @SuppressWarnings("unused")
         private Message() throws JHOVE2Exception{
              this(null, null, null, null, null, null);
         }
         /**
          * Instantiate a new Localized <code>Message</code>.
          * 
          * @param severity
          *            Message severity
          * @param context
          *            Message context
          * @param messageCode
          *            Key to message text in localized property file
          * @param configInfo 
          * @throws JHOVE2Exception 
          */
         public Message(Severity severity, Context context, String messageCode, ConfigInfo configInfo)
              throws JHOVE2Exception
         {
              this(severity, context, messageCode, new Object[0], defaultLocale, configInfo);
         }
         
         /**
          * Instantiate a new Localized <code>Message</code>.
          * 
          * @param severity
          *            Message severity
          * @param context
          *            Message context
          * @param messageCode
          *            Key to message text in localized property file
          * @param messageArgs
          *                Arguments to message format template
          * @param configInfo 
          *            ConfigInfo containing method to localize method text
          * @throws JHOVE2Exception
          */
         public Message(Severity severity, Context context, String messageCode,
                          Object[] messageArgs, ConfigInfo configInfo) 
              throws JHOVE2Exception
         {
              this(severity, context, messageCode, messageArgs, defaultLocale, configInfo);
         }
    
         /**
          * Instantiate a new Localized <code>Message</code>.
          * 
          * @param severity
          *            Message severity
          * @param context
          *            Message context
          * @param messageCode
          *            Key to message text in localized property file
          * @param messageArgs
          *                Arguments to message format template
          * @param locale
          *                  Locale for message text
          * @param configInfo TODO
          * @throws JHOVE2Exception
          */
         public Message(Severity severity, Context context, String messageCode, 
                          Object[] messageArgs, Locale locale, ConfigInfo configInfo)
              throws JHOVE2Exception
         {
              this.severity = severity;
              this.context = context;
              this.locale = locale;
              this.messageCode = messageCode;
              this.configInfo = configInfo;
              this.localizedMessageText = this.localizeMessageText(messageCode, messageArgs, locale);
         }
    
         /**
          * Resolves message code and produces localized message text
          * @param messageCode
          *            Key to message text in localized property file
          * @param messageArgs
          *                  Arguments to message format template
          * @param locale
          *             Locale for message text
          * @return  
          *         Localized formatted message text
          * @throws JHOVE2Exception
          */
         protected String localizeMessageText(String messageCode, Object[] messageArgs,
                                                Locale locale) 
              throws JHOVE2Exception
         {
              String localizedMessage = null;
              localizedMessage = this.getConfigInfo().getLocalizedMessageText(messageCode, 
                        messageArgs, locale);
              return localizedMessage;
         }
    
         /** Get message context.
          * @return Message context
          */
         public Context getContext() {
              return context;
         }
    
         /** Get localized message text.
          * @return Localized message text
          */
         public String getLocalizedMessageText() {
              return localizedMessageText;
         }
    
         /** Get message code.
          * @return Message code
          */
         public String getMessageCode() {
              return messageCode;
         }
    
         /** Get message severity
          * @return Message severity
          */
         public Severity getSeverity() {
              return severity;
         }
    
         /** Set message context.
          * @param context Message context
          */
         public void setContext(Context context) {
              this.context = context;
         }
    
         /** Set localized message text.
          * @param localizedMessageText Localized message text
          */
         public void setLocalizedMessageText(String localizedMessageText) {
              this.localizedMessageText = localizedMessageText;
         }
         
         /** Set message code.
          * @param messageCode Message code
          */
         public void setMessageCode(String messageCode) {
              this.messageCode = messageCode;
         }
    
         /** Set message severity.
          * @param severity Message severity
          */
         public void setSeverity(Severity severity) {
              this.severity = severity;
         }
    
         /**
          * Get {@link java.lang.String} representation of the message.
          */
         @Override
         public String toString() {
              return "[" + this.severity + "/" + this.context + "] " + this.localizedMessageText;
         }
    
         /**
          * @return the configInfo
          */
         public ConfigInfo getConfigInfo() {
              return configInfo;
         }
    
         /**
          * @param configInfo the configInfo to set
          */
         public void setConfigInfo(ConfigInfo configInfo) {
              this.configInfo = configInfo;
         }
    }
    
    
    // and you will of course recognizer the proxy for Locale
    @Persistent(proxyFor=Locale.class)
    public class LocalePersisentProxy implements PersistentProxy<Locale> {
    
        String language;
        String country;
        String variant;
    
         private LocalePersisentProxy() {}
    
         @Override
         public Locale convertProxy() {
              return new Locale(language, country, variant);
         }
    
         @Override
         public void initializeProxy(Locale object) {
              language = object.getLanguage();
            country = object.getCountry();
            variant = object.getVariant();
    
         }
    
    }
  • 7. Re: Problem persisting a @Persistent class
    greybird Expert
    Currently Being Moderated
    Thanks for posting the complete classes. Hopefully this will give Eric enough information to see what's happening. He will take a look at it tonight (he is in China) and reply then.
    --
    mark
  • 8. Re: Problem persisting a @Persistent class
    788289 Newbie
    Currently Being Moderated
    Thanks so much to you both.

    If you need to see more of, or indeed all of, the source code -- I would be happy to zip it up and send it to you - -the code is an open-source project, available under BSD License - -and we are perfectly happy to make any of it available for inspection if that would help your detective work.

    Thanks again for the efforts you're expending.

    Sheila
  • 9. Re: Problem persisting a @Persistent class
    788289 Newbie
    Currently Being Moderated
    NB - -just realized in Souce code above, left off mutator setFileSourceIdentifier () method for BerkeleyDbIdentifierAccessor class -- here is the complete class:
    @Persistent
    class BerkeleyDbIdentifierAccessor extends BerkeleyDbBaseModuleAccessor
    implements IdentifierAccessor {
    
         public BerkeleyDbIdentifierAccessor(){
              super();
         }
         /* (non-Javadoc)
          * @see org.jhove2.persist.IdentifierAccessor#getFileSourceIdentifier(org.jhove2.module.identify.Identifier)
          */
         @Override
         public FileSourceIdentifier getFileSourceIdentifier(Identifier module)
         throws JHOVE2Exception {
              FileSourceIdentifier fsi = null;
              if (module != null){
                   try{
                        Module rModule = 
                             this.getBerkeleyDbPersistenceManager().
                             getFileSourceIdentifierByParentIdentifier().get(module.getModuleId());
                        if (rModule != null){
                             fsi = (FileSourceIdentifier)rModule;
                        }
                   }
                   catch(DatabaseException e){
                        throw new JHOVE2Exception("Unable to retrieve FileSourceIdentifier",e);
                   }
              }
              return fsi;
         }
    
         /* (non-Javadoc)
          * @see org.jhove2.persist.IdentifierAccessor#setFileSourceIdentifier(org.jhove2.module.identify.Identifier, org.jhove2.module.identify.FileSourceIdentifier)
          */
         @Override
         public FileSourceIdentifier setFileSourceIdentifier(Identifier module,
                   FileSourceIdentifier fileSourceIdentifier) throws JHOVE2Exception {
    
              if (module != null && fileSourceIdentifier != null){
                   if (module.getModuleId()== null){
                        module = (Identifier) this.persistModule(module);
                   }
                   
                   //un-link old FileSourceIdentifier
                   FileSourceIdentifier oldFsi = this.getFileSourceIdentifier(module);
                   if (oldFsi != null){
                        oldFsi.setParentIdentifierId(null);
                        oldFsi = (FileSourceIdentifier) this.persistModule(oldFsi);
                   }
    
                   fileSourceIdentifier.setParentIdentifierId(module.getModuleId());
                   fileSourceIdentifier = (FileSourceIdentifier) this.persistModule(fileSourceIdentifier);
              }          
              return fileSourceIdentifier;
         }
    
    }
  • 10. Re: Problem persisting a @Persistent class
    788289 Newbie
    Currently Being Moderated
    Also -- here is the data access class that manages indexes, etc.
    public class BerkeleyDbPersistenceManager implements PersistenceManager {
    
         protected EnvironmentConfig envConfig;
         protected StoreConfig storeConfig;
         protected String envHome;
         protected String entityStoreName;
         
         protected Environment env;
         protected EntityStore store;
         
         PrimaryIndex<Long, AbstractSource> sourceBySourceId;
         SecondaryIndex<Long, Long, AbstractSource>  sourceByParentSource;
         
         PrimaryIndex<Long, AbstractModule> moduleByModuleId;
         SecondaryIndex<Long, Long, AbstractModule> moduleByParentSource;
         SecondaryIndex<Long, Long, AbstractDisplayer> displayerByParentApp;
         SecondaryIndex<Long, Long, BaseFormatProfile> formatProfileByParentFormatModule;
         SecondaryIndex<Long, Long, AbstractCommand> commandByParentFramework;
         SecondaryIndex<Long, Long, GlobPathRecognizer> recognizerByParentAggrefier;
         SecondaryIndex<Long, Long, DROIDIdentifier> fileSourceIdentifierByParentIdentifier;
              
         public BerkeleyDbPersistenceManager() {
              super();
         }
    
    
         @Override
         public void initialize() throws JHOVE2Exception {
              File envHomeFile = new File(envHome);
              boolean exists = envHomeFile.exists();
              if (!exists){
                   boolean couldMakeDirs = envHomeFile.mkdirs();
                   if (!couldMakeDirs){
                        throw new JHOVE2Exception("Could not create BerkeleyDB env home path "+
                                  envHome);
                   }
              }
              boolean isDir = envHomeFile.isDirectory(); 
              if (!isDir){
                   throw new JHOVE2Exception("BerkeleyDB env home path " +
                             envHome + " is not a directory");
              }
              try{
                   env = new Environment(envHomeFile, envConfig);               
                   EntityModel model = new AnnotationModel();
                   
                   // register sub-classes for indexes
                   model.registerClass(AbstractDisplayer.class);
                   model.registerClass(AbstractApplication.class);
                   model.registerClass(BaseFormatModule.class);
                   model.registerClass(BaseFormatProfile.class);
                   model.registerClass(JHOVE2.class);
                   model.registerClass(AggrefierModule.class);
                   model.registerClass(GlobPathRecognizer.class);
                   model.registerClass(AbstractCommand.class);
                   model.registerClass(IdentifierModule.class);
                   model.registerClass(DROIDIdentifier.class);
                   
                   //register proxies
                   model.registerClass(LocalePersisentProxy.class);
                   model.registerClass(PatternPersistentProxy.class);
                   
                   storeConfig.setModel(model);                              
                   store = new EntityStore(env,entityStoreName,storeConfig);
                        
                   // create indexes for Source entities
                   sourceBySourceId = 
                        this.getStore().getPrimaryIndex(Long.class, AbstractSource.class);               
                   sourceByParentSource = 
                        this.getStore().getSecondaryIndex(sourceBySourceId, Long.class, "parentSourceId");
                   // create indesxes for Module entities
                   moduleByModuleId = 
                        this.getStore().getPrimaryIndex(Long.class, AbstractModule.class);
                   moduleByParentSource =
                        this.getStore().getSecondaryIndex(moduleByModuleId, Long.class, "parentSourceId");
                   displayerByParentApp =
                        this.getStore().getSubclassIndex(moduleByModuleId, AbstractDisplayer.class, Long.class, "parentAppId");
                   formatProfileByParentFormatModule =
                        this.getStore().getSubclassIndex(moduleByModuleId, BaseFormatProfile.class, Long.class,"formatModuleId");
                   commandByParentFramework =
                        this.getStore().getSubclassIndex(moduleByModuleId, AbstractCommand.class, Long.class,"jhove2ModuleId");
                   recognizerByParentAggrefier =
                        this.getStore().getSubclassIndex(moduleByModuleId, GlobPathRecognizer.class, Long.class, "parentAggrefierId");
                   fileSourceIdentifierByParentIdentifier =
                        this.getStore().getSubclassIndex(moduleByModuleId, DROIDIdentifier.class, Long.class, "parentIdentifierId");
              }
              catch (Exception e){
                   throw new JHOVE2Exception ("Cannot initialize Berkeley DB environment", e);
              }
         }
    
         @Override
         public void close() throws JHOVE2Exception {
              if (this.getStore()!= null){
                   try {
                        this.getStore().close();
                   }
                   catch(DatabaseException e){
                        throw new JHOVE2Exception("Unable to close database Store",e);               
                   }
              }
              if (this.getEnv()!= null){
                   try{
                        this.getEnv().close();
                   }
                   catch(DatabaseException e){
                        throw new JHOVE2Exception("Unable to close database Environment",e);               
                   }
              }
              return;
         }
    
         public EnvironmentConfig getEnvConfig() {
              return envConfig;
         }
         public void setEnvConfig(EnvironmentConfig envConfig) {
              this.envConfig = envConfig;
         }
    
         public StoreConfig getStoreConfig() {
              return storeConfig;
         }
    
         public String getEnvHome() {
              return envHome;
         }
         public Environment getEnv() {
              return env;
         }
         public EntityStore getStore() {
              return store;
         }
         public void setStoreConfig(StoreConfig storeConfig) {
              this.storeConfig = storeConfig;
         }
         public void setEnvHome(String envHome) {
              this.envHome = envHome;
         }
         public void setEnv(Environment env) {
              this.env = env;
         }
         public void setStore(EntityStore store) {
              this.store = store;
         }
         public String getEntityStoreName() {
              return entityStoreName;
         }
         public void setEntityStoreName(String entityStoreName) {
              this.entityStoreName = entityStoreName;
         }
    
         public PrimaryIndex<Long, AbstractSource> getSourceBySourceId() {
              return sourceBySourceId;
         }
         public SecondaryIndex<Long, Long, AbstractSource> getSourceByParentSource() {
              return sourceByParentSource;
         }
    
         public PrimaryIndex<Long, AbstractModule> getModuleByModuleId() {
              return moduleByModuleId;
         }
    
         public SecondaryIndex<Long, Long, AbstractModule> getModuleByParentSource() {
              return moduleByParentSource;
         }
    
         public SecondaryIndex<Long, Long, AbstractDisplayer> getDisplayerByParentApp() {
              return displayerByParentApp;
         }
         public SecondaryIndex<Long, Long, BaseFormatProfile> getFormatProfileByParentFormatModule() {
              return formatProfileByParentFormatModule;
         }
         public SecondaryIndex<Long, Long, AbstractCommand> getCommandByParentFramework() {
              return commandByParentFramework;
         }
         public SecondaryIndex<Long, Long, GlobPathRecognizer> getRecognizerByParentAggrefier() {
              return recognizerByParentAggrefier;
         }
         public void setSourceBySourceId(
                   PrimaryIndex<Long, AbstractSource> sourceBySourceId) {
              this.sourceBySourceId = sourceBySourceId;
         }
         public void setSourceByParentSource(
                   SecondaryIndex<Long, Long, AbstractSource> sourceByParentSource) {
              this.sourceByParentSource = sourceByParentSource;
         }
         public void setModuleByModuleId(
                   PrimaryIndex<Long, AbstractModule> moduleByModuleId) {
              this.moduleByModuleId = moduleByModuleId;
         }
         public void setModuleByParentSource(
                   SecondaryIndex<Long, Long, AbstractModule> moduleByParentSource) {
              this.moduleByParentSource = moduleByParentSource;
         }
         public void setDisplayerByParentApp(
                   SecondaryIndex<Long, Long, AbstractDisplayer> displayerByParentApp) {
              this.displayerByParentApp = displayerByParentApp;
         }
         public void setFormatProfileByParentFormatModule(
                   SecondaryIndex<Long, Long, BaseFormatProfile> formatProfileByParentFormatModule) {
              this.formatProfileByParentFormatModule = formatProfileByParentFormatModule;
         }
         public void setCommandByParentFramework(
                   SecondaryIndex<Long, Long, AbstractCommand> commandByParentFramework) {
              this.commandByParentFramework = commandByParentFramework;
         }
         public void setRecognizerByParentAggrefier(
                   SecondaryIndex<Long, Long, GlobPathRecognizer> recognizerByParentAggrefier) {
              this.recognizerByParentAggrefier = recognizerByParentAggrefier;
         }
         public SecondaryIndex<Long, Long, DROIDIdentifier> getFileSourceIdentifierByParentIdentifier() {
              return fileSourceIdentifierByParentIdentifier;
         }
         public void setFileSourceIdentifierByParentIdentifier(
                   SecondaryIndex<Long, Long, DROIDIdentifier> fileSourceIdentifierByParentIdentifier) {
              this.fileSourceIdentifierByParentIdentifier = fileSourceIdentifierByParentIdentifier;
         }
    
    }
  • 11. Re: Problem persisting a @Persistent class
    712739 Newbie
    Currently Being Moderated
    Hi, Sheila,

    Thanks for posting so much useful information.

    I create almost the same class hierarchies in my sandbox (using JE 4.0.103) based on your posted source code. However, I can persist these persistent (especially IdentifierModule) classes, and cannot reproduce the error you met.

    I said "almost the same" means that the persistent member fields in each class are the same, but I remove some of the methods in your provided source code, which have nothing to do with the DPL persistent process.

    My suggestion is that can you give me your email address, so I can send you the source code which runs successfully in my sandbox. Then you can make some comparison to see why your code cannot work. I doubt that there must be some wrong modifier settings for member fields (e.g., public, static).

    If it is not convenient for you to provide your email address here, you can contact me via email. My email is: haomian.wang at oracle.com
  • 12. Re: Problem persisting a @Persistent class
    788289 Newbie
    Currently Being Moderated
    Eric - -thanks so much -- you can reach me at sheila.morrissey@ithaka.org -- I would very much appreciate looking at the code.

    Thanks again
    Sheila
  • 13. Re: Problem persisting a @Persistent class
    788289 Newbie
    Currently Being Moderated
    Eric has with great perserverence got to the bottom of this -- the BerkeleyDbIdentifierAccessor class itself did NOT have a "public" access modifer. Adding the modifier fixed the problem.

    Disussion trail below - -many thanks from me and my team members to Eric & Co. for all the time and effort they spent on this.
    Hi, Sheila,
    
    On 9/8/2010 12:41 AM, Sheila M. Morrissey wrote:
    
    The problem seems to occur when I try to perist an instance of an IdentifierModule that has been persisted once before  -- here from the JUNIT test
    
                   IdentifierModule myIdModule = new IdentifierModule(new BerkeleyDbIdentifierAccessor());
                   myIdModule = (IdentifierModule) myIdModule.getModuleAccessor().persistModule(myIdModule);
                   assertEquals(1L, myIdModule.getModuleId().longValue());          
                   myIdModule = (IdentifierModule) myIdModule.getModuleAccessor().persistModule(myIdModule); // this throws the exception we are seeing
                   assertEquals(1L, myIdModule.getModuleId().longValue());
      
    I have reproduced this error in my sandbox.
    
    But I notice that there are no any modifiers for the definition of the class BerkeleyDbIdentifierAccessor. After I add "public" modification to it, which means (add the bold "public"):
    @Persistent
    public class BerkeleyDbIdentifierAccessor extends BerkeleyDbBaseModuleAccessor
    implements IdentifierAccessor {
    the test can run successfully.
    
    Is there any limitation to avoiding adding "public" modifications into BerkeleyDbIdentifierAccessor definition? If not, please adding "public" modifications into BerkeleyDbIdentifierAccessor definition to see what will happen. 
    
    Please let me know the result.
    
    Thanks.
    
    -- 
    Best regards.
    Haomian (Eric), Wang
    Berkeley DB, Java Edition
    Oracle
    
    
    Eric –
    Thanks so much - -this was the problem!!
    
    A lesson certainly to me the importance of Exception error messages –  the message from java.lang.reflect*
    Caused by: com.sleepycat.je.EnvironmentFailureException: (JE 4.0.103) java.lang.IllegalAccessException: Class com.sleepycat.persist.impl.ReflectionAccessor can not access a member of class org.jhove2.persist.berkeleydpl.BerkeleyDbIdentifierAccessor with modifiers "public" UNEXPECTED_EXCEPTION: Unexpected internal Exception, may have side effects 
    had me scrutinizing fields INSIDE BerkeleyDbIdentifierAccessor, without looking at the access modifier of the class itself.
    
    Am curious why the FIRST persist worked, but subsequent ones did n
    
    Thanks on behalf of my entire team.
    
    Sheila
  • 14. Re: Problem persisting a @Persistent class
    712739 Newbie
    Currently Being Moderated
    In a future release, we will have a fix that DPL can persist a non-public persistent class. For the current or previous releases, the best workaround is to make the persistent class public.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points