Load java classes, error in type of arguments (Signed url of GCP)

I’m playing with google-cloud-storage java implementation.

I’m trying to do something like this:

	var storageOption = CreateObject("java", "com.google.cloud.storage.StorageOptions");

    // now, i try to add credential to storageOption 
	var credentials = CreateObject("java", "com.google.auth.oauth2.ServiceAccountCredentials");
	var configFile = CreateObject("java", "java.io.FileInputStream").init( ExpandPath('/google-config.json') );

	credentials.fromStream( configFile );
	var storage = storageOption.newBuilder()
		.setCredentials( credentials ) //here raise an error

here, i get this error:

No matching Method/Function for com.google.cloud.storage.HttpStorageOptions$Builder.setCredentials(lucee.runtime.java.JavaObject) found

but “credentials”, passed to setCredentials(), is instance of “com.google.auth.Credentials” (as expected) not “lucee.runtime.java.JavaObject”, like error says.

    dump( isInstanceOf( credentials, "com.google.auth.Credentials") );

I’m translate code from here:

Any idea?
Many thanks!

Here full stacktrace:

OS: Windows 11
Java Version: Java 11.0.11 (AdoptOpenJDK)
Lucee Version: 5.3.9+133

This might simply be an issue with order. Try something like this:

	// load storage options
	var storageOption = CreateObject("java", "com.google.cloud.storage.StorageOptions");

	// load storage with direct invocations of java functions
	var storage = storageOption.newBuilder()
			createObject( 'java', 'com.google.auth.oauth2.ServiceAccountCredentials' )
	            createObject( 'java', 'java.io.FileInputStream' ).init(
	                expandPath( '/google-config.json' )
		) //here raise an error

That said, make sure the path to your config file translates correctly as it may not be able to make a credential object if the file isn’t located and may then result in something else being passed in there (like the java object).

Also, I followed what was done in the example so this should load the inputFileStrem using the fromStream loader of the NewBuilder from the storage option which should be the proper path with no interim variables (that may get converted to a lucee java object).

If that all fails then I’d check if StorageOptions needs any initiailization to be passed in or if fileInputStream needs any action outside of init to be useful to .fromStream() (I would assume, without reading the docs that fromStream() executes a read() on the stream, but if it doesn’t that might be another avenue to explore why credentials is failing).

Best guesses in a white coat, so ymmv, but hope that helps!

– Denny

Maybe try using the FixedCredentialsProvider instead.

I spent a while working with the analytics Google API a while back. It looks like a similar setup, so this may or may not be of help to you. The way that I got it working was as follows:

local.gapiSettings = createObject("java", "com.google.analytics.data.v1beta.BetaAnalyticsDataSettings");
local.FileInputStream = createObject("java", "java.io.FileInputStream").init(variables._credentialsPath);
local.GoogleCredentials = object("com.google.auth.oauth2.GoogleCredentials").fromStream(local.FileInputStream);

local.fixedCredentials = object("com.google.api.gax.core.FixedCredentialsProvider").create(local.GoogleCredentials);

local.analyticsData = createObject("java", "com.google.analytics.data.v1beta.BetaAnalyticsDataClient");

local.dataSettings = local.gapiSettings.newBuilder().setCredentialsProvider(local.fixedCredentials).build()

return local.analyticsData.create(local.dataSettings);


1 Like

Thanks @ddspringle @martin !

I leave here the working code, to get a signed url from the com.google.cloud.storage API.
I hope it can be of use to someone.

	var keyFile = CreateObject("java", "java.io.FileInputStream").init( ExpandPath('/key.json') );
	var storage = CreateObject("java", "com.google.cloud.storage.StorageOptions")
	var credentials = CreateObject("java", "com.google.auth.oauth2.ServiceAccountCredentials")
						.fromStream( keyFile );
	var blobInfo = CreateObject("java", "com.google.cloud.storage.BlobInfo");
	var BlobId = CreateObject("java", "com.google.cloud.storage.BlobId");
	var uri = storage.signUrl(
				blobInfo.newBuilder(BlobId.of(bucketName, blobName)).build(), 
				CreateObject("java", "java.util.concurrent.TimeUnit").MINUTES,
					CreateObject("java", "com.google.cloud.storage.Storage$SignUrlOption").signWith(
	dump(uri.toString()); //url available for 10 minutes