Azure-Samples / azure-sdk-for-java-storage-blob-upload-download

How to upload and download blobs from Azure Blob Storage with Java
16 stars 34 forks source link

Caused by: java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit #5

Closed ksurendra closed 5 years ago

ksurendra commented 6 years ago

When running the program locally (on my mac), seeing the below error.

String accountName = "acsazurestore";
String accountKey = "DefaultEndpointsProtocol=https;AccountName=xx;AccountKey=xxx";
// Create a ServiceURL to call the Blob service. We will also use this to construct the ContainerURL
SharedKeyCredentials creds = new SharedKeyCredentials(accountName, accountKey);

Caused by: java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit at java.util.Base64$Decoder.decode0(Base64.java:704) at java.util.Base64$Decoder.decode(Base64.java:526) at java.util.Base64$Decoder.decode(Base64.java:549) at com.microsoft.azure.storage.blob.SharedKeyCredentials.<init>(SharedKeyCredentials.java:60) at quickstart.Quickstart.main(Quickstart.java:160)

I had to comment out the createTempFile and downloadFile since running locally.

darewreck54 commented 6 years ago

From https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-java-v10, it states to use the key and not the connection string for the account key.

I'm not sure if the document is incorrect or not.

If I just use the Connection string, I get the same error you have but on windows.

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 org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:293) at java.lang.Thread.run (Thread.java:748) Caused by: java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit at java.util.Base64$Decoder.decode0 (Base64.java:704) at java.util.Base64$Decoder.decode (Base64.java:526) at java.util.Base64$Decoder.decode (Base64.java:549) at com.microsoft.azure.storage.blob.SharedKeyCredentials.<init> (SharedKeyCredentials.java:60) at quickstart.Quickstart.main (Quickstart.java:158) 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 org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:293) at java.lang.Thread.run (Thread.java:748)

When i use the key, i get the following error:

>> Creating a sample file at: C:\Users\dehang\AppData\Local\Temp\sampleFile638755363879210956.txt
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Service error returned: 400

You can get ride of the SLF4j by adding this to your dependency pom file

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.7.25</version>
    </dependency>

but still get the error:

>> Creating a sample file at: 
\AppData\Local\Temp\sampleFile7670907418933364328.txt
Service error returned: 400
[WARNING] thread Thread[SharedChannelPool-worker,5,quickstart.Quickstart] was interrupted but is still alive after waiting at least 14999msecs
[WARNING] thread Thread[SharedChannelPool-worker,5,quickstart.Quickstart] will linger despite being asked to die via interruption
[WARNING] thread Thread[RxSchedulerPurge-1,5,quickstart.Quickstart] will linger despite being asked to die via interruption
[WARNING] thread Thread[RxCachedWorkerPoolEvictor-1,5,quickstart.Quickstart] will linger despite being asked to die via interruption
[WARNING] thread Thread[RxComputationThreadPool-1,5,quickstart.Quickstart] will linger despite being asked to die via interruption
[WARNING] thread Thread[RxComputationThreadPool-2,5,quickstart.Quickstart] will linger despite being asked to die via interruption
[WARNING] thread Thread[nioEventLoopGroup-1-1,5,quickstart.Quickstart] will linger despite being asked to die via interruption
[WARNING] thread Thread[nioEventLoopGroup-1-2,5,quickstart.Quickstart] will linger despite being asked to die via interruption
[WARNING] thread Thread[nioEventLoopGroup-1-3,5,quickstart.Quickstart] will linger despite being asked to die via interruption
[WARNING] NOTE: 8 thread(s) did not finish despite being asked to  via interruption. This is not a problem with exec:java, it is a problem with the running code. Although not serious, it should be remedied.
[WARNING] Couldn't destroy threadgroup org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup[name=quickstart.Quickstart,maxpri=10]
java.lang.IllegalThreadStateException
    at java.lang.ThreadGroup.destroy (ThreadGroup.java:778)
    at org.codehaus.mojo.exec.ExecJavaMojo.execute (ExecJavaMojo.java:328)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:290)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:194)
    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 org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
[INFO] ------------------------------------------------------------------------
darewreck54 commented 6 years ago

If you step through the code in main, you are required to use the key not the actual connection string. It will fail to connect on lines:

      // Create a ServiceURL to call the Blob service. We will also use this to construct the ContainerURL
            SharedKeyCredentials creds = new SharedKeyCredentials(accountName, accountKey);
            // We are using a default pipeline here, you can learn more about it at https://github.com/Azure/azure-storage-java/wiki/Azure-Storage-Java-V10-Overview
            final ServiceURL serviceURL = new ServiceURL(new URL("http://" + accountName + ".blob.core.windows.net"), StorageURL.createPipeline(creds, new PipelineOptions()));
dennyac commented 6 years ago

@darewreck54 you are correct. We need to use the key and not the actual connection string.

The storage account you created may have the "Secure transfer required" option as "Enabled". If that is the case, just change the request to https.

final ServiceURL serviceURL = new ServiceURL(new URL("https://" + accountName + ".blob.core.windows.net"), StorageURL.createPipeline(creds, new PipelineOptions()));

That should be fixed in this PR - https://github.com/Azure-Samples/storage-blobs-java-v10-quickstart/pull/6

seguler commented 5 years ago

Issue fixed. Thanks!