Java Spring Boot - Read a file from the Resources folder inside a . jar

Asked

Viewed 1,474 times

3

I am writing a class that will read an ETL Pentaho Kettle (transformation). I have put the file that the class will read in the Resources / KTR folder.

But when I try to run the code as a java application (java -jar), I get an error saying that the file does not exist.

However, he is trying to read the local disk file and not from inside my . jar.

How I read the file from inside the . jar?

I am using Spring Boot 2.1.0.BUILD-SNAPSHOT and Java 1.8.

public class run_tranform {

 public static void main( String[] args ) throws IOException
{
 String file="src/main/resources/KTR/transformation.ktr";

    try {
        KettleEnvironment.init();
        //TransMeta metaData = new TransMeta(file.getPath());
        TransMeta metaData = new TransMeta(file);
        Trans trans = new Trans( metaData );
        trans.execute( null );
        trans.waitUntilFinished();
        if ( trans.getErrors() > 0 ) {
            System.out.print( "Error Executing transformation" );
        }
    } catch( KettleException e ) {
        e.printStackTrace();
    }
   }

 }
  • Hey, Diego, I don’t know if you noticed, but this site is in Portuguese. So, you should have posted in Portuguese. I’ve already translated your question for you.

1 answer

1

First, I suggest you follow the language conventions and instead of naming his class as run_transform, name her as RunTransform.

You can get a InputStream for the resource within the JAR when using the method getResourceAsStream with the syntax of Try-with-Resources thus:

String resource = "/KTR/transformation.ktr";
try (InputStream is = RunTransform.class.getResourceAsStream(resource)) {
    // ...
}

However, the class TransMeta does not have a builder who receives only one InputStream or just one Reader replacing the one who receives a File. There is only one constructor with the parameters TransMeta(InputStream, Repository, boolean, VariableSpace, OverwritePrompter):

    public TransMeta(InputStream xmlStream, Repository rep, boolean setInternalVariables, VariableSpace parentVariableSpace, OverwritePrompter prompter ) throws KettleXMLException
    {
        loadXML( XMLHandler.loadXMLFile(xmlStream, null, false, false), rep, setInternalVariables, parentVariableSpace, prompter);
    }

So let’s take a look at constructor you are using, which gets a File:

   public TransMeta(String fname) throws KettleXMLException
    {
        this(fname, true);
    }

This calls a another builder:

    public TransMeta(String fname, boolean setInternalVariables) throws KettleXMLException
    {
        this(fname, null, setInternalVariables);
    }

That calls another:

    public TransMeta(String fname, Repository rep, boolean setInternalVariables ) throws KettleXMLException
    {
        this(fname, rep, setInternalVariables, null);
    }

That calls yet another:

    public TransMeta(String fname, Repository rep, boolean setInternalVariables, VariableSpace parentVariableSpace ) throws KettleXMLException
    {
        this(fname, rep, setInternalVariables, parentVariableSpace, null);
    }

One more:

   public TransMeta(String fname, Repository rep, boolean setInternalVariables, VariableSpace parentVariableSpace, OverwritePrompter prompter ) throws KettleXMLException
    {
        // ... Um monte de coisas aqui
    }

In this last constructor, the signature is almost the same as the desired constructor, with the difference that the first parameter is String instead of InputStream. In both the constructor you call and the desired, there is a call to a method loadXML. In the desired construct, as the first parameter to this method, we have this:

XMLHandler.loadXMLFile(xmlStream, null, false, false)

That method returns a Document. Already the builder with String carries the Document file and uses it to call the method loadXML.

It follows then that you have to replace this:

TransMeta metaData = new TransMeta(file);

That’s why:

TransMeta metaData = new TransMeta(stream, null, true, null, null);

Its resulting code is this:

import java.io.IOException;
import java.io.InputStream;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;

public class RunTransform {
    public static void main(String[] args) throws IOException {
        String resource = "/KTR/transformation.ktr";
        try (InputStream is = RunTransform.class.getResourceAsStream(resource)) {
            KettleEnvironment.init();
            TransMeta metaData = new TransMeta(stream, null, true, null, null);
            Trans trans = new Trans(metaData);
            trans.execute(null);
            trans.waitUntilFinished();
            if (trans.getErrors() > 0) {
                System.out.print("Error Executing transformation");
            }
        } catch (KettleException e) {
            e.printStackTrace();
        }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.