Execute .jar file in Spoon (Pentaho Kettle) - java

I need to execute a java jar file from Spoon.
The program has only one class, and all I want is to run it with or without parameters.
The class is named "Limpieza", and is inside a package named:
com.overflow.csv.clean
I have deploy the jar to:
C:\Program Files (x86)\Kettle\data-integration\lib
And from a Modified JavaScriptValue step, I am calling it this way:
var jar = com.everis.csv.clean.Limpieza;
This is not working at all, is there a way around to make it work?
Also would be nice to have a way to see the logs printed by the program when it runs.
I am not getting any error when I run the transformation.
Thanks.

Check the blog below:
https://anotherreeshu.wordpress.com/2015/02/07/using-external-jars-import-in-pentaho-data-integration/
Hope this might help :)

Spoon will load any jar files present in its
data-integration\lib
folder and its subfolders during startup, so if you want to access classes from a custom jar, you could place the jar here.
So you need to create a custom jar and place the jar in
data-integration\lib
location.
While calling a custom class in "Modified Java Script Value" or in "User Defined Java Class step" you should call with fully qualified name. For example var jar = com.everis.csv.clean.Limpieza.getInstance().getMyString();
Note: After placing the jar, make sure you restart the Spoon.
If still does not work please attach the Pentaho.log (data-integration-server/logs/Pentaho.log) and catalina.out(data-integration-server/tomcat/logs) logs

The answer was to create a User Defined Java Class (follow the guide Rishu pointed), and here is my working code:
import java.util.*;
import com.everis.csv.Cleaner;
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
{
Cleaner c = new Cleaner();
c.clean();
// The rest of it is for making it work
// You will also need to make a Generate Rows step that inputs a row to this step.
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
r = createOutputRow(r, data.outputRowMeta.size());
putRow(data.outputRowMeta, r);
return true;
}

Related

Make a cloned jar file of itself

hey guys i just make some changes to the previous one ....
that is
import java.io.*;
import java.nio.*;
public class Test1234{
public static void main(String args[]){
File inputF = new File(Test1234.class.getProtectionDomain().getCodeSource().getLocation().getFile());
File outputF = new File("D:\\test.class");
FilePermission adb = new FilePermission(inputF.getPath(),"write,read,execute");
Files.copy(inputF.toPath(),outputF.toPath(),REPLACE_EXISTING);
}
}
for simplicity the inputF points to the class file itself. And it compiles perfect. but when i found the file test.class it only is an empty folder.
so please guys help me !!! I'm stuck with this problem.
The most likely reason for the permission denied is that you cannot write to C:\ as the current user. Chose a folder you can write to or run as administrator.
Since you are running a plain main method there is very probably no SecurityManager, plus you would get a SecurityException if that was the problem. Also, it does not matter whether you read the current code source, only on Windows you cannot delete or write to it since this would be locked by the OS.
If that is not the problem, you need to verify Test1234.class.getProtectionDomain().getCodeSource().getLocation().getPath() points to what you actually want to copy. A stack trace would help in that case.
i just found out the solution by building my class file to jar file. then when i run it, it created a cloned jar file named test.jar. by when i just say this one you must change the outputF path to "d:\test.jar". :)

Can i rename package paths of an existing jar packages?

i have a ready to use .jar file and want to know if its possible to extract and rename the packages?
so when usually i start the .jar file with:
java -cp myFile.jar com.codehelper.demo.Main
i want to rename the "codehelper" in it to something different that i can run it by
java -cp myFile.jar com.NEW_NAME.demo.Main
i tried to decompile all files, add it to the folderstructure with renamed "codehelper" path and compile it again but it didnt work. i also renamed all the package includes in each file like
import com.codehelper...
so is my goal unreachable or can i do this? and if someone can explain me how to do, it will be very nice.
thank you and sory for my poor english
edit: it seems the only file i cant compile is a file containing this switch case.
private int priotiryLevel(DiscoveryInfoBehave info)
{
int ret = 0;
switch (1.$SwitchMap$com$peerialism$natcracker$common$GatewayDevice$GatewayType[info.getNatDevice().getGatewayType().ordinal()])
{
case 1:
ret = 0;
break;
case 2:
ret = 4;
break;
case 3:
ret = 5;
break;
}
return ret;
}
i tried also to rename the specific word inside this switch case but no effort.
Write a new wrapper class:
package com.NEW_NAME.demo;
public class Main
{
public static void main(String[] args)
{
com.codehelper.demo.Main.main(args);
}
}
compile it and add it to the jar. You can now invoke it as:
java -cp myFile.jar com.NEW_NAME.demo.Main
and it will silently dispatch to the real implementation.
This is not possible generally. If you rename some files, Java wont be able to find them (public class name must be same as file name). You can rename file with main class and call it as #Joe suggested in his answer. But if you rename somthing else, it will stop working. There could be cals to those classes in code. Same goes for the "codehelper" name. You can not remove it from code. Even if you remove it from one file, anyone will still be able to see this somewhere else in the code.
Rename directory is the same as rename file. You destroy namespace (package) and code will no longer work, because inside classes, this package is used. Plus there is no need to have import in the code, since you can call directly com.package-name.class from the executive code. By renaming package, you will destroy this and program will crash. It may run for a while, but once the program reach to this call, it will crash.
So this
import com.codehelper...
is not mandatory in the code, even if the code is using the package. You can write directly
com.codehelper.*** xy = new com.codehelper.***();
Even if you rename everything in the code, you still dont have guaranted functionality. Code may be using reflection and create class instances from sting code. For example see this:
Java how to instantiate a class from string
Under the line comment:
Doing some decompile -> compile work, is seems like code stealing, if you are not willing to pay licence and you want to hide it.
Plus doing something like this, it is ALWAYS a bad practice. I dont see any real use for this.

Hadoop setting fsPermission recursively to dir using Java

Hi I have test program which loads files into hdfs at this path user/user1/data/app/type/file.gz Now this test program runs multiple times by multiple users. So I want to set file permission to rwx so that anyone can delete this file. I have the following code
fs.setPermission(new Path("user/user1/data"),new FsPermission(FsAction.ALL,FsAction.ALL,FsAction.ALL))
Above line gives drwxrwxrwx to all dirs but for the file.gz it gives permission as -rw-r--r-- why so? Because of this reason another user apart from me not able to delete this file through test program. I can delete file through test program because I have full permssion.
Please guide. I am new to Hadoop. Thanks in advance.
Using FsShell APIs solved my dir permission problem. It may be not be optimal way but since I am solving it for test code it should be fine.
FsShell shell=new FsShell(conf);
try {
shell.run(new String[]{"-chmod","-R","777","user/usr1/data"});
}
catch ( Exception e) {
LOG.error("Couldnt change the file permissions ",e);
throw new IOException(e);
}
I think Hadoop doesn't provide a java API to provide permission recursively in the version you are using. The code is actually giving permission to the dir user/user1/data and nothing else. You should better use FileSystem.listStatus(Path f) method to list down all files in the directory and use Filsystem.setPermission to them individually. It's working currently on my 2.0.5-alpha-gphd-2.1.0.0 cluster.
However from Hadoop 2.2.0 onward a new constructor
FsPermission(FsAction u, FsAction g, FsAction o, boolean sb)
is being provided. The boolean field may be the recursive flag you wanted. But the documentation(including param name) is too poor to infer something concrete.
Also have a look at Why does "hadoop fs -mkdir" fail with Permission Denied? although your sitaution may be different. (in my case dfs.permissions.enabled is still true).
I wrote this in scala but I think you could easily adapt it:
def changeUserGroup(user:String,fs:FileSystem, path: Path): Boolean ={
val changedPermission = new FsPermission(FsAction.ALL,FsAction.ALL,FsAction.ALL, true)
val fileList = fs.listFiles(path, true)
while (fileList.hasNext()) {
fs.setPermission(fileList.next().getPath(),changedPermission)
}
return true
}
You will also have to add a logic for the error handling, I am always returning true.

JAVA download command in matlab code [duplicate]

I want Matlab program to call a java file, preferably with an example.
There are three cases to consider.
Java built-in libraries.
That is, anything described here. These items can simply be called directly. For example:
map = java.util.HashMap;
map.put(1,10);
map.put(2,30);
map.get(1) %returns 10
The only complication is the mapping Matlab performs between Matlab data types and Java data types. These mappings are described here (Matlab to Java) and here (Java to Matlab). (tl; dr: usually the mappings are as you would expect)
Precompiled *.jar files
You first need to add these to Matlab's java class path. You can do this dynamically (that is, per-Matlab session, with no required Matlab state), as follows:
javaaddpath('c:\full\path\to\compiledjarfile.jar')
You can also add these statically by editing the classpath.txt file. For more information use docsearch java class path.
Precompiled *.class files.
These are similar to *.jar file, except you need to add the directory containing the class file, rather than the class files themselves. For example:
javaaddpath('c:\full\path\to\directory\containing\class\files\')
%NOT THIS: javaaddpath('c:\full\path\to\directory\containing\class\files\classname.class')
Ok, I'll try to give a mini-example here. Either use the java functions right from the Matlab window as zellus suggests, or, if need permits, create your own java class. Here's an example:
package testMatlabInterface;
public class TestFunction
{
private double value;
public TestFunction()
{
value = 0;
}
public double Add(double v)
{
value += v;
return value;
}
}
Then turn it into a jar file. Assuming you put the file in a folder called testMatlabInterface, run this command at the command line:
jar cvf testMatlab.jar testMatlabInterface
Then, in Matlab, navigate to the directory where your testMatlab.jar file is located and run the command, import testMatlabInterface.* to import all the classes in the testMatlabInterface package. Then you may use the class like so:
>> methodsview testMatlabInterface.TestFunction
>> me = testMatlabInterface.TestFunction()
me =
testMatlabInterface.TestFunction#7e413c
>> me.Add(10)
ans =
10
>> me.Add(10)
ans =
20
>> me.Add(10)
ans =
30
Let me know if I can be of further assistance.

Make JAR as a standalone executable

Is there a way to convert JAR lib into JAR standalone?
I need to find a standalone java executable that convert PDF into TIFF and I've found these JARs: http://www.icefaces.org/JForum/posts/list/17504.page
Any ideas?
Easiest might be to create another Jar with a Main() entry point, and then just use the java.exe executable to run it:
e.g.
> java.exe -cp MyJarMain.jar;MyPDFJar.jar com.mydomain.MyMain myPDF.pdf
Where MyMain is a class with a Main static method.
You'll need something with a main entry point to pass in and interpret some command line arguments (myPDF.pdf in my made-up example)
You could do an assembly (are you using maven?) and make sure the Main-Class entry in the manifest.mf points to the main class.
Since there is no main-Method, you have to write one, or write a whole new class to call the class/method TiffConver.convertPDF .
The question is, how you're going to use it. From the command line, you need no executable jar. From the Gui, maybe you want to pass a file to be converted by drag and drop? Then you should take the parameter(s) passed to main as Input-PDF-Names (if they end in .pdf) and pass the names iteratively to TiffConverter, for "a.pdf b.pdf" =>
TiffConver.convertPDF ("a.pdf", "a.tiff");
TiffConver.convertPDF ("b.pdf", "b.tiff");
TiffCoverter will silently overwrite existing tiffs, so check that before or change the code there - this is clearly bad habit, and look out for more such things - I didn't.
/*
* Remove target file if exists
*/
File f = new File(tif);
if (f.exists()) {
f.delete();
}
Maybe you wan't to write a swing-wrapper, which let's you choose Files interactively to be converted. This would be a nice idee, if no filename is given.
If the user passes "a.pdf xy.tiff" you could rename the converted file to xy, as additional feature.
Without a main-class, however, a standalone jar would be magic.
However, building a native executale is almost always a bad idea. You loose portability, you don't profit from security- and performance improvements to the JVM or fixed bugs. For multiple programs you need always an independend bugfix, which you might have to manage yourself, if you don't have a package-management as most linux distros have.
after clearing some questions:
public static void main (String [] args) {
if (args.length == 1 && args[0].endsWith (".pdf")) {
String target = args[0].replaceAll (".pdf$", ".tif");
convertPDF (args[0], target);
}
}
This method you put into TiffConvert. It will allow you to convert a simple pdf-File, and generate a tif-File with the same basename but ending in .tif, silently overwriting an existing one of the same name.
I guess you now need to know how to start it?

Categories

Resources