Reading a file from the local file system and saving it as binary data, using Grails

{ Posted on 6:49 PM by Alex P. }
I'm relatively new to Grails and recently ran into some difficulty when attempting to save a file, read in from the local file system, as a long-blob to MySQL. Most of the documentation I found dealt with saving of single files, uploaded by users of the website front-end. My situation was a little different. My application needed to accept jar file uploads through the front-end, requiring that I extract and recreate the entire jar's directory structure onto the server's local file system, before further processing and validation. The original data contained in these files would ultimately have to be saved to the database. One of these file types were java class files and needed to be stored into a MySQL database long_blob field as binary data.

Below is the way I created the domain class for these class files. I've omitted some fields for the sake of simplicity. Our class files' binary data will be stored into the 'byteCode' field. The code in the mapping closure is needed to make this work.

package org.netbeans.portals.admin

import java.sql.Blob;

class FileClass {
String fileName;
Blob byteCode;
Date createdAt = new Date();

static constraints = {
fileName(unique: true, nullable: false)
byteCode(nullable: false)
createdAt(nullable: false)
}

static mapping = {
columns {
byteCode type: "blob"
}
}
}


Below, is some simple code that returns a java.sql.Blob object, provided the path to a file, as a String. It converts the file into byte array, using the 'getBytesFromFile' method listed beneath it. using Hibernate's 'createBlob' method gives us the required sql blob which we can simple assign to our FileClass object's byteCode field.

    def getSqlBlobFromFile(String path) {
file = new File(path)
bytes = this.getBytesFromFile(file)
java.sql.Blob sqlBlob = null
if (bytes) {
sqlBlob = org.hibernate.Hibernate.createBlob(bytes)
}
return sqlBlob
}


***DISCLAIMER: I did not write the code, below.***
This is one of countless examples of converting a file to a byte array that can be found throughout the web. Unfortunately, I do not recall where I found it.

    private static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
// Get the size of the file
long length = file.length();
if (length > Integer.MAX_VALUE) {
// File is too large
return null
}
// Create the byte array to hold the data
byte[] bytes = new byte[(int)length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
// Close the input stream and return bytes
is.close();
return bytes;
}


I hope this helps

Java Resource Injection

{ Posted on 11:31 AM by Ralph Tavarez }
If you are creating an API it may be necessary to provide resources to the API client. Many APIs use XML configuration files, resource files, or additional helper classes / methods to provide access to resources. All of which increase the learning curve required to utilize your code. Ideally your API should simplify resource provisioning and consumption. My personal preference is to follow the current trend towards annotations as an API convention.

In this post I will cover the convention of resource utilization via annotation and I will cover how to inject the resource by utilizing Java reflection. To clarify the convention, the client needs to annotate one or more fields and the fields must be of the proper Java type. If the client meets the conditions, the API container will automatically assign an appropriate resource to the client's field member even of the field is not public.

To demonstrate how this is done I will create a simple client:

package sample;

import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.NamingException;

public class InjectionClient {
//field to be injected with required jndi name property
@ResourceProvider(jndiName="jdbc/MyPool")
private ConnectionProvider provider;

public void foo(String sql)
throws NamingException, SQLException {
Connection con = null;

try {
// provider already set by container
con = provider.getConnection();

// ... do something useful
} finally {
try {
if (con != null) con.close();
} catch (SQLException ex) {}
}
}
}


Notice how simple and clean the code is for the client to consume the resource. Simply define a member of the correct type and annotate accordingly. Next lets look at the annotation being used by the client:

package sample;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// Annotation to be used for field declarations
@Target(ElementType.FIELD)
// Record annotation in the class file and make it available at run time
@Retention(RetentionPolicy.RUNTIME)
public @interface ResourceProvider {
String jndiName();
}



In this case the annotation tells the client that a jndi name is require. It also tells the client that the annotation is used for field declarations which will be recorded in the class file and will be accessible during runtime. The nice part of the annotation as part of an API is that most Java IDE's will help validate the proper usage of the annotation.

Finally lets take a look at the injection code:

package sample;

import java.lang.reflect.Field;

public class Injector {
public static void injectConnectionResource(Object o)
throws IllegalArgumentException, IllegalAccessException {
ResourceProvider a;

// iterate threw the fields
for (Field field : o.getClass().getDeclaredFields()) {
// set accessibility just in case the field is private
field.setAccessible(true);

// get the required annotation
a = field.getAnnotation(ResourceProvider.class);

// validate type and annotation
if (a != null && field.getType().isAssignableFrom(ConnectionProvider.class)) {
// inject
field.set(o, new ConnectionProvider(a.jndiName()));
}
}
}
}



To complete the example below is the code for the actual resource provider:

package sample;

import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class ConnectionProvider {
private String jndiName;

public ConnectionProvider(String jndiName) {
this.jndiName = jndiName;
}

public Connection getConnection() throws NamingException, SQLException {
InitialContext context = new InitialContext();
DataSource dataSource = (DataSource) context.lookup(jndiName);
Connection con = dataSource.getConnection();

return con;
}
}


There are 2 gotchas with this approach:

1)If the field is set to anything other than public you may have an issue. Refection allows you to suppress Java language access checking but this only works if the no security manager is present. If a security manager is present then the “suppressAccessChecks” reflection permission must not be flagged as true.

2)Reflection is slow, painfully slow.

Gotcha's aside, resource injection via reflection based on annotation convention is a great approach to simplify an API.