Error while trying to download/export the files by using the DFC code

Options

Hi,

While trying to download/export the files by using the DFC code getting following error.

2024-03-20 19:01:17 ERROR PDFMergingMethods:2063 - -Exception while exporting the Object ID 09030fa4802fff37
org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Premature end of file.
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:257)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:338)
    at com.documentum.services.config.impl.ConfigFile.loadXML(Unknown Source)
    at com.documentum.services.config.impl.ConfigFile.<init>(Unknown Source)
    at com.documentum.services.config.impl.ConfigService.newConfigFile(Unknown Source)
    at com.documentum.operations.impl.config.reader.ConfigReader.addConfigFile(ConfigReader.java:40)
    at com.documentum.operations.impl.config.reader.ConfigReader.addConfigFiles(ConfigReader.java:34)
    at com.documentum.operations.impl.config.reader.JarReader.loadConfigFiles(JarReader.java:81)
    at com.documentum.services.config.impl.ConfigService.initialiseApp(Unknown Source)
    at com.documentum.services.config.impl.ConfigService.initialiseApp(Unknown Source)
    at com.documentum.services.config.impl.ConfigService.loadConfig(Unknown Source)
    at com.documentum.operations.impl.config.ConfigManager.initializeConfigService(ConfigManager.java:439)
    at com.documentum.operations.impl.config.ConfigManager.newConfigService(ConfigManager.java:336)
    at com.documentum.operations.impl.config.ConfigManager.getConfigService(ConfigManager.java:499)
    at com.documentum.operations.impl.config.ConfigManager.lookupOperation(ConfigManager.java:107)
    at com.documentum.operations.DfOperation.getDefinition(DfOperation.java:103)
    at com.documentum.operations.outbound.DfExportOperation.getDefinition(DfExportOperation.java:46)
    at com.documentum.operations.impl.OperationNodeTreeBuilder.populate(OperationNodeTreeBuilder.java:567)
    at com.documentum.operations.impl.OperationNodeTreeBuilder.add(OperationNodeTreeBuilder.java:65)
    at com.documentum.operations.DfOperation.add(DfOperation.java:323)
    at com.PDFMergingMethods.exportDocument(PDFMergingMethods.java:2082)
    at com.PDFMergingMethods.exportDocbyObjectID(PDFMergingMethods.java:2056)
    at com.PDFMergingMethods.exportDocumentbyObjectID(PDFMergingMethods.java:1960)
    at com.PDFMerge.oneDMSDocDownload(PDFMerge.java:23)
    at com.PDFMerge.main(PDFMerge.java:46)

Is this cause by access related issue? 

I am able to view content via dqMan(third party product) successfully.

Answers

  • Without seeing any code, it's hard to say. Can you share some snippets of how you get the document in DFC and how you export it?

  • Hi Francois,

    Please find below the DFC code snippet for exporting the documents from repository:-

    private String exportDocument (DocumentBean docBean, String target_local_directory) throws DfException{

    	// Create a new client instance.
    IDfClientX clientx = new DfClientX();

    //Creating the Export operation object
    IDfExportOperation eo = clientx.getExportOperation();

    // Create a document object that represents the document being exported.
    IDfDocument doc = (IDfDocument) _idfSession.getObject(new DfId(docBean.getObject_id()));

    // Create an export node, adding the document to the export operation object.
    IDfExportNode node = (IDfExportNode)eo.add(doc);

    //Setting the Destination directory to which the Documents will be exported to
    node.setFilePath(target_local_directory+docBean.getObject_id()+"."+docBean.getContentType());

    DfLogger.info(this,"Exporting the document in temp path: "+target_local_directory+docBean.getObject_id()+"."+docBean.getContentType(), null, null);

    if (eo.execute()){
    DfLogger.info(this,"Object ID "+docBean.getObject_id()+" exported successfully", null, null);
    return "Export operation successful.";
    }else{
    DfLogger.error(this,"Object ID "+docBean.getObject_id()+" export operation failed.", null, null);
    return "Export operation failed.";
    }
    }

  • Typically, when I need to export content, I don;t bother with the export operation, in my experience, I get the DfDocument and I use the getContent method on it.

    Less coding😉

    Once, when I started programing, in the prehistory, my mentor told me that a good developer is a lazy developer, the less lines in the code the better. Believe you me, that'd 1 advice I've always followed 🤣

  • Hi Francois,

    I understand your approach, what would you suggest we should do in current situation.

    Can you also point out the problem in existing code as it will be easier to fix the issue that way.

  • After the line IDfDocument doc = (IDfDocument) _idfSession.getObject(new DfId(docBean.getObject_id()));

    I'd remove all the export stuff and just do a doc.getFile(target_local_directory+docBean.getObject_id()+"."+docBean.getContentType());

    In 2 lines of code, you'd have your content exported….

  • The IDfOperation classes have an added benefit of abstracting ACS/Network location, etc. By using the IDfOperation classes you should get the benefits of the platform services. It does require a bit more code but you can chain multiple objects in one operation for a transaction. Working with one object at a time, I admit even I take the quick and low code route most of the time BUT if I need distributin/acs, etc (client side DFC) I might take the IDfOperation route.

    What version of DFC are you using?
    What is the format of the object you are exporting?

    Assuming the exception is thrown here:

    IDfExportNode node = (IDfExportNode)eo.add(doc);

    can you try by doing:
    IDfSysObject doc = (IDfSysObject) _idfSession.getObject(new DfId(docBean.getObject_id()));

    Instead? I generally use IDfSysObject and the javadocs "imply" it:

    If that works, let me know. You will still also need:

    1. (Perhaps, it may default to native format but not sure) node.setFormat(doc.getFormat().getName())
    2. eo.execute
    3. In case your file does not export, there is a node.getErrors() to parse to give you any errors that occured.

    Do let me know if any of the above helps, if so I may file a bug on preventing IDfDocument (not saying this is the problem, just using my somewhat dated knowledge when I used to develop more for a living) :)

  • Reason I asked about DFC version is there is an older version bug that causes a SaxParser exception I found but that is a REALLY old 6.5 version so I would not expect that to happen now. But if there are mutliple versions of SAX libraries in your classpath, "maybe".

    I used your code, fetching a simple text document and was able to export using same sequence you used in your code without issue. I am Dfc 23.2 with my tests.

  • Good point Michael, I went straight to the quick and dirty solution since looking at the code, it seemed like it was 1 object at the time.

    An executive that keep their hands under under the hood, like that. Not too many of us left out there 😉

  • Thanks for your advice Michael,

    Our problem is now solved, your response was very insightful and well-defined, As you asked in the previous post we are using Documentum v23.2

    We have a method, in which we pass robject id as a parameter and it is supposed to download the document associated with the robject id into local memory, however in some cases we get an "r object id does not exist" exception even when a document with the r_object id is present. Can you provide any solution to this issue, It occurs over the same code shared beforehand.

  • When you create an object, you can an object id. However that does not mean it is saved or available to another session. The most likely causes of your issue are:

    One process or session creates an object and returns an ID to another process before saving it or the ID was returned BUT the save failed. In your code I see there is a bean that stores the objectId so you could be persisting an objectID that was never persisted to the Documentum content store. I would start looking in that direction.

  • Hi Michael,

     Regarding the issue that you pointed out, we first store the document from diffrent sources via APIs(DFS, Rest) into the Documentum, after that we query Documentum for list of r_object_ids and document name to display, the r object id passed while downloading is from the list that we get in response to the previous query itself (from the above code). Therefore I am not sure if we will be getting an r object id for a document that was not saved.

  • Sure, this is an area where it would be troubleshooting your processes/code is needed. Without something specific to look at/narrow to, anything at this point would be a wild guess. If there are things that were validated there by other processes, I would look to enable audit events so you can see what other processes could be failing or deleting, etc. Are you able to reproduce any of this with any type of unit tests?

    You don't by chance use 2 different repositories for say dev and test with same name/docbase id do you? I have seen problems where someone clones a dev docbase to a test docbase and then a situation I call "cross-pollination" could happen. One danger of using/cloning an environment to another is that is is easy to mix things up between the 2 distinct repositories. One process saves to Repo A1, the other is fetching (what woudl be a valid id returned from A1 but is not in A2. Again, this is just a wild guess with an uncommon scenario but I have seen it.

  • Another obvious one is the permission issue : you create the document as one user (ACL gets assigned either explicitly or based on default settings) and retrieve the document as another user who has NONE permission.

  • HI Hicham,

    We are uploading and download the documents from single user.

  • It is really hard to know what is going on without a complete picture (code). There has to be a problem in coding here that would cause this. When you get the object not found exception, you could also then (in the catch block) query for any audit events (dm_save) on that object id to determine if you are trying to prematurely fetch the object (catch the audit trail timestamp in relation to your stack exception for object not found).

  • I remember in the prehistory when it was still Desktop Client and Documentum was still as company, not only a product, that I had a similar issue. The only way I found at the time was that once I created the object, in the app creating the object, I would fetch it.

    BEfore I did that, sometimes other apps on other machines would find it, sometimes not, after, it was always found….

    I know it sounds crazy but who knows….

  • Hi Michael,

    In our implementation, we have created a web application that queries documents from the repository using the DFC code, the arguments passed for this function are r_object ID which is used to fetch the documents and the docbasename, username and password are used to authenticate in docbase, the document corresponding to the r_object ID is then received in it's native format and is then converted to Base64 string locally. Then it will send base64encoded string to the calling application.

  • Sure makes sense but if you query an object by qualification or fetch an object by ID, it will exist unless it was not saved or deleted.

  • OR…. if it was created by one session but not yet persisted and another session tried to fetch it.

  • Ram_Kishan_Maitry
    edited March 28 #21
    Options

    Hi Michael,

    We are using below code for exporting/downloading the documents from repository. Please suggest improvements on this.

    private DocumentBean exportDocbyObjectID(String docId, String contentType){

    	BeanModule _m = new BeanModule();
    String status = "";
    DocumentBean doc = new DocumentBean();
    try {
    doc.setObject_id(docId);
    doc.setContentType(contentType);
    status = exportDocument(doc,_m.get_tempFilepath());

    if(!status.equalsIgnoreCase("Export operation successful.")){
    doc.setObject_id("");
    }
    }catch(Exception e) {
    doc.setObject_id("");
    DfLogger.error(this,"-Exception while exporting the Object ID "+docId, null, e);
    }finally{
    status = null;
    }
    return doc;
    }

    private String exportDocument(DocumentBean docBean, String target_local_directory) throws DfException{

    // Create a new client instance.
    IDfClientX clientx = new DfClientX();

    //Creating the Export operation object
    IDfExportOperation eo = clientx.getExportOperation();

    // Create a document object that represents the document being exported.
    IDfSysObject doc = (IDfSysObject) _idfSession.getObject(new DfId(docBean.getObject_id()));
    doc.getFile(target_local_directory+docBean.getObject_id()+"."+docBean.getContentType());

    if (StringUtils.isBlank(doc.getObjectId().toString())){
    return "Export operation failed.";
    }else {
    return "Export operation successful.";
    }
    }

  • Hi Michael,

    Did you get a chance to go through the shared code?

  • Sorry, sometimes it may be days before I get a chance to look here. It is more of a free time activity (which is few and far between).

    Where does the docId come from? How is that obtained?

  • Ram_Kishan_Maitry
    edited March 29 #24
    Options

    Hi Michael,

    Thanks for response.

    We are following below steps before exporting/downloading the documents:-

    Step 1:- We are retrieving(i.e. r_object_id, object_name,a_content_type, r_creation_date) the list of documents from repository based on some key(department name).

    Step 2:- Showing the list on documents in front-end application.

    Step 3:- When I click on any documents from the front-end application, it internally calls the exportDocbyObjectID(r_object_id,a_content_type) method to view/download the documents from the repository.

  • Are you able to reproduce this with any type of Unit testing? THis is pseudo code, not complete

    String dql = select r_object_id, object_name, a_content_type, r_creation_date from {insert type name here} where department_name = 'xxxxxxx'

    IDfCollection col = null;

    try {

    col = runQuery(sql) // need to setup IDfQuery in this method and return collection
    while(col.next()) {
    logger.debug("Found objectId: " + col.getString("r_object_id") +
    " Name: " + col.getString(col.getString("object_name") + " Modified: " +
    col.getString("r_modify_date"));

    String docId = col.getString("r_object_id");

    BeanModule _m = new BeanModule();
    String status = "";
    DocumentBean doc = new DocumentBean();
    try {
    doc.setObject_id(docId);
    doc.setContentType(contentType);
    status = exportDocument(doc,_m.get_tempFilepath());
    if(!status.equalsIgnoreCase("Export operation successful.")){
    doc.setObject_id("");
    }
    }catch(Exception e) {
    doc.setObject_id("");
    DfLogger.error(this,"-Exception while exporting the Object ID "+docId, null, e);
    }finally{
    status = null;
    }

    } // end loop

    } catch (Exception e) {
    col.close();
    }

    public static IDfCollection runQuery(IDfSession session, String dql) throws DfException {
        IDfQuery query = new DfQuery();
        query.setDQL(dql);
        return query.execute(session,
              ((dql.toLowerCase().trim().startsWith("select")) ? DfQuery.DF_READ_QUERY : DfQuery.DF_EXEC_QUERY));
    }
    

    The bean info for name, date, etc might give some correlateable data to figure out what is going on as well. If the object is not returned/does not exist, it one of:

    1. Was not persisted (create object without save or failed save/exception)
    2. No permissions for the user running the export (or browse only permission vs. read)
    3. Object was deleted