1

I have a java program that is an extension to product. I wish to check if a file has changed and then copy it if it has.

I am using a ClassLoader to get the resource so I can get the last modified date. i:e

        boolean copyFile = false;
    String fileName = getRhumbaDirectory()+"\\stockexchanges.dict";
    try {
            File file = new File(fileName);
            Long fileLastModified = file.lastModified();
            URL url = this.getClass().getClassLoader().getResource("com/moneydance/modules/features/securityquoteload/resources/stockexchanges.dict");
            Long resourceLastModified=0L;
            if (url !=null) {
                resourceLastModified = url.openConnection().getLastModified();
            }
            debugInst.debug("ExchangeList", "getData", MRBDebug.INFO, "Modified Date "+fileLastModified+" "+ resourceLastModified);     
            if (resourceLastModified > fileLastModified)
                copyFile = true;
    }
    catch (IOException e){
        copyFile = true;
    }
    if (copyFile) {
        try {
            InputStream input = this.getClass().getClassLoader().getResourceAsStream("com/moneydance/modules/features/securityquoteload/resources/stockexchanges.dict");
            if (input == null) {
                debugInst.debug("ExchangeList", "getData", MRBDebug.INFO, "Problem creating stockexchanges.dict file");     
            }
            else {
                FileOutputStream output = new FileOutputStream(fileName);
                byte [] buffer = new byte[4096];
                int bytesRead = input.read(buffer);
                while (bytesRead != -1) {
                    output.write(buffer, 0, bytesRead);
                    bytesRead = input.read(buffer);
                }
                output.close();
                input.close();
            }
        }
        catch (IOException f) {
            debugInst.debug("ExchangeList", "getData", MRBDebug.DETAILED, "Problem copying default file"+f.getMessage());       
            f.printStackTrace();
        }

    }

The code

                URL url = this.getClass().getClassLoader().getResource("com/moneydance/modules/features/securityquoteload/resources/stockexchanges.dict");

Returns null whilst the code

                InputStream input = this.getClass().getClassLoader().getResourceAsStream("com/moneydance/modules/features/securityquoteload/resources/stockexchanges.dict");

returns a valid stream. Shouldn't they both work?

  • Hi@Mikerb [read this](https://stackoverflow.com/a/625712/5813861) which is answered by jon skeet. – yash Sep 17 '18 at 12:52
  • Find more details [here](https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getResource%28java.lang.String%29) – yash Sep 17 '18 at 12:57
  • Hi yash I changed the getResource to ExchangeList.class.getResource("/com/moneydance/modules/features/securityquoteload/resources/stockexchanges.dict") as per Jon's comments. It too returned null. –  Sep 17 '18 at 13:01
  • What does `System.out.println(this.getClass().getClassLoader().getClass())` print? (I wonder if this is caused by some custom classloader with inconsistent implementations of `getResource` and `getResourceAsStream` ...) – Stephen C Sep 17 '18 at 13:17
  • Hi @yash Interesting the text at your link is virtually the same for getResource and getResourceAsStream –  Sep 17 '18 at 13:22
  • Thanks @Stephen C. It prints out class com.moneydance.apps.md.controller.ModuleLoader$FMClassLoader which is obviously an adapted loader. I now have to work out how to get around it. –  Sep 17 '18 at 13:32

1 Answers1

0

Thanks to '@Stephen C' his suggestion found the reason. This forum will not be able to provide the work around as it is proprietary to the app.