Reading an uploaded file in a timer?

I’m looking to read one of three files from a timer based on some state in a database, though I can’t find any method to actually do this. I’m trying to compose an email with an HTML body and I want to read from a file instead of, say, a database field or a String literal.

I have this code to get the file URL after doing a directory search:

	private String read(String resourceName) throws IOException {
    Iterator<FileInfo> filesIterator = Backendless.Files.listing("/resources").getCurrentPage().iterator();
		
    while (filesIterator.hasNext()) {
        FileInfo next = filesIterator.next();
        if (next.getName().equals(resourceName)) {
        /* snip */
    }


After I get the FileInfo object, I attempt to open a connection to the file like this:

				URL fileURL = new URL(next.getPublicUrl());




				URLConnection connection = fileURL.openConnection();




Calling URL#openConnection() throws an exception, though:


SEVERE: Could not initialize class sun.security.pkcs.SignerInfo


...


/* snip */


...


Caused by: java.lang.NoClassDefFoundError: Could not initialize class sun.security.pkcs.SignerInfo




The file is available for you via basic HTTP GET operation

There are numerous of ways of how to download a file from the Internet using Java

Choose what fits best for your

Missed the Reply button the first time, so I posted above.

Sorry, I don’t think I was clear enough.

The timer I’m using is a Backendless timer (implementation of TimerExtender). When I call URL#openConnection, it’s running on your servers, so the exception is thrown while executing on your environment, which is why I’m posting here.

I just want to read the contents of the file into a String and then set that String (after some light modification) into an email body with a call to Backendless.Messaging.sendHTMLEmail();

The StackOverflow URL you posted has an accepted answer for transferring a file. I don’t want to transfer a file, I just want to read it’s contents into a StringBuilder.

Just repeated all steps and was able successfully read the file.
Make sure you import URL and URLConnection classes from java.net package

Those classes are imported from the java.net package.

I’ve tried a couple of things. Here’s the full stack trace. You can tell from the full stack trace that the correct packages are imported:

[INFO] Deploying model to server, and starting debug…
[INFO] Model successfully deployed.
[INFO] Waiting for events…
Jan 27, 2017 3:44:15 AM com.backendless.coderunner.runtime.task.EventInvocationTask runImpl
SEVERE: Could not initialize class sun.security.pkcs.SignerInfo
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.backendless.coderunner.runtime.task.EventInvocationTask.runImpl(EventInvocationTask.java:113)
at com.backendless.coderunner.runtime.concurrent.ExtendedRunnable.run(ExtendedRunnable.java:26)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class sun.security.pkcs.SignerInfo
at sun.security.pkcs.PKCS7.parseSignedData(PKCS7.java:392)
at sun.security.pkcs.PKCS7.parse(PKCS7.java:186)
at sun.security.pkcs.PKCS7.parse(PKCS7.java:154)
at sun.security.pkcs.PKCS7.<init>(PKCS7.java:136)
at sun.security.util.SignatureFileVerifier.<init>(SignatureFileVerifier.java:118)
at java.util.jar.JarVerifier.processEntry(JarVerifier.java:297)
at java.util.jar.JarVerifier.update(JarVerifier.java:228)
at java.util.jar.JarFile.initializeVerifier(JarFile.java:383)
at java.util.jar.JarFile.getInputStream(JarFile.java:450)
at javax.crypto.JceSecurity.loadPolicies(JceSecurity.java:300)
at javax.crypto.JceSecurity.setupJurisdictionPolicies(JceSecurity.java:262)
at javax.crypto.JceSecurity.access$000(JceSecurity.java:48)
at javax.crypto.JceSecurity$1.run(JceSecurity.java:80)
at java.security.AccessController.doPrivileged(Native Method)
at javax.crypto.JceSecurity.<clinit>(JceSecurity.java:77)
at javax.crypto.JceSecurityManager.<clinit>(JceSecurityManager.java:65)
at javax.crypto.Cipher.getConfiguredPermission(Cipher.java:2587)
at javax.crypto.Cipher.getMaxAllowedKeyLength(Cipher.java:2611)
at sun.security.ssl.CipherSuite$BulkCipher.isUnlimited(CipherSuite.java:535)
at sun.security.ssl.CipherSuite$BulkCipher.<init>(CipherSuite.java:507)
at sun.security.ssl.CipherSuite.<clinit>(CipherSuite.java:614)
at sun.security.ssl.SSLContextImpl.getApplicableCipherSuiteList(SSLContextImpl.java:293)
at sun.security.ssl.SSLContextImpl.access$100(SSLContextImpl.java:41)
at sun.security.ssl.SSLContextImpl$AbstractTLSContext.<clinit>(SSLContextImpl.java:424)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at java.security.Provider$Service.getImplClass(Provider.java:1634)
at java.security.Provider$Service.newInstance(Provider.java:1592)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:164)
at javax.net.ssl.SSLContext.getInstance(SSLContext.java:156)
at javax.net.ssl.SSLContext.getDefault(SSLContext.java:96)
at javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java:122)
at javax.net.ssl.HttpsURLConnection.getDefaultSSLSocketFactory(HttpsURLConnection.java:332)
at javax.net.ssl.HttpsURLConnection.<init>(HttpsURLConnection.java:289)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.<init>(HttpsURLConnectionImpl.java:85)
at sun.net.www.protocol.https.Handler.openConnection(Handler.java:62)
at sun.net.www.protocol.https.Handler.openConnection(Handler.java:57)
at java.net.URL.openConnection(URL.java:979)
at java.net.URL.openStream(URL.java:1045)
at com.organtime.WeeklyEmail.read(WeeklyEmail.java:76)
at com.organtime.WeeklyEmail.emailTop(WeeklyEmail.java:53)
at com.organtime.WeeklyEmail.generateBody(WeeklyEmail.java:37)
at com.organtime.WeeklytimerTimer.execute(WeeklytimerTimer.java:45)
… 7 more

Hi Alex,

Does the same happen in debug mode, when the code is running on your computer?

No, this is happening while the code is running in the Backendless environment on Backendless hardware.

What version of JDK are you using?

SE 8u121.

Is it Oracle or OpenJDK?

Oracle, i updated to that version just before I started working on the timer extension, actually.

Downloaded from http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html .

Can you please also provide the output of “java -version” on your machine?

Absolutely, though I need to get home to do that. It’ll take a couple hours. Thank you in advance for your patience.

Okay, I was able to get the printout.

C:\Users\username>java -version

java version “1.8.0_121”
Java™ SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot™ 64-Bit Server VM (build 25.121-b13, mixed mode)

C:\Users\username>javac -version
javac 1.8.0_121

I changed things around a bit and tried loading the file using the File() class instead.

Now I’m getting this error:

SEVERE: access denied (“java.io.FilePermission” “https:\api.backendless.com\AE7A9021-884C-EE6A-FFF0-DE7BEEE17700\v1\files\resources\email_html_top.txt” “read”)

I tried using the solution here but I can’t find the security.policy file to edit it:
http://support.backendless.com/t/cant-open-https-urls#comment-10483

Can you please send a minimal example of the code reproducing the problem to support@backendless.com?

I just had a breakthrough.

The thrown exception was a bit of a red herring since it didn’t actually say much about the problem. PKCS is used to manage TLS handshaking in this case, which was the hint I used to figure out the problem.

The security.policy file was not in the CodeRunner.jar as the support ticket above indicated. It was in the same directory as the CodeRunner.jar instead. Once I uncommented the permission java.security.AllPermission line, everything worked as expected.

Given the number of questions in your support forums about this, I would say you should update your documentation when running code in the debug environment. The exception is cryptic at best.