Options

Importing jar files for script operartor

wesselwessel Member Posts: 537 Maven
edited November 2018 in Help
Dear All,

Is it possible to make imports to third party jar files in the script operator?
For example:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

I'm unsure when I can set the class path so it actually recognizes these classes.

Best regards,

Wessel

Answers

  • Options
    Nils_WoehlerNils_Woehler Member Posts: 463 Maven
    Hi Vessel,

    RM6 builds the classpath on-the-fly when being started. Just put the .jar file in the /lib folder. Afterwards you should be able to import the classes (if the .jar's dependencies are fulfilled).

    Best,
    Nils
  • Options
    wesselwessel Member Posts: 537 Maven
    What about RM5?
  • Options
    Nils_WoehlerNils_Woehler Member Posts: 463 Maven
    For RM5 it should probably also work like this. We have changed the start-up mechansim from 5 to 6 so I'm not 100% sure.
  • Options
    wesselwessel Member Posts: 537 Maven
    Thanks!
  • Options
    elnecesarioelnecesario Member Posts: 5 Contributor II
    Hi all,

    I hope it's ok to answer to this topic, otherwise please just move this topic or tell me to do so...

    I am using RM5 community version and want to include my jar-file so that I can use it in the script-operator.
    But copying the jar-file to the lib folder did not work for me....I always get the error java.lang.NoClassDefFoundError. Could this be caused by missing dependencies in my jar-file? My jar-file only contains Logger.class and Logger$1.class.

    Logger.java:

    package testPackage;

    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.StringWriter;
    import java.io.PrintWriter;

    import java.lang.Exception;

    import javax.swing.JFileChooser;
    import javax.swing.JOptionPane;
    import javax.swing.SwingUtilities;


    /**
    * the Logger class to log Strings and Exceptions (for exceptions, the stack trace can be logged if wanted)
    */
    public class Logger {

    private String log;
    private String path;
    private String suffix;
    private BufferedWriter bWriter = null;
    private boolean active = false;
    public final String FILE_SEP = File.separator;
    public final String HOME_DIR = System.getProperty("user.home");
    public final String FOLDER = "ML" + FILE_SEP + "logFiles";

    /**
    * the constructor. The logger is NOT activated by default!
    * @param path the path for the Logger to be saved. If the path is "", the path is set to the users desktop.
    * @param nameSuffix the name Suffix (the prefix is an index number, so that old log files are not getting overriden)
    */
    public Logger (String path, String nameSuffix) {
    this.log = "";
    this.path = path;
    this.suffix = nameSuffix;
    }

    /**
    * activetes the logger. Creates the logger File, preferable in currentUser/Desktop/DAI/logFiles. User prompt, if no valid path could be found.
    */
    public void activate() throws Exception{
    this.active = true;
    if (this.bWriter == null) {
    boolean pathFound = findPath();
    if (pathFound) {
    createFile();
    } else {
    showUserSelectPathPrompt();
    }
    }
    }

    /**
    * disables the logger. This will not remove the loggerFile. It will just make sure that no more log messages are being saved.
    */
    public void disable() {
    this.active = false;
    }

    /**
    * pops up a dialog to choose a folder to save the log files in.
    */
    private void showUserSelectPathPrompt() throws Exception{
    JFileChooser chooser = new JFileChooser();
    chooser.setDialogTitle("choose your folder for saving the log files.");
        int returnVal = chooser.showOpenDialog(null);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
        path = chooser.getSelectedFile().getPath();
        createFile();
        } else {
        SwingUtilities.invokeLater(new Runnable() {
        public void run() {
        JOptionPane.showMessageDialog(null, "No valid folder was selected, so no log files will be created.");
        }
      });
        this.active = false;
        }
    }

    /**
    * find the Desktop path
    * @return returns true if the desktopPath could be found and false if not.
    */
    private boolean findPath() {
    String[] possibleDesktopNames = new String[4];
    possibleDesktopNames[0] = "Desktop";
    possibleDesktopNames[1] = "Arbeitsplatz";
    possibleDesktopNames[2] = "Schreibtisch";
    possibleDesktopNames[3] = "Arbeitsfläche";

    File f = new File("");
    for (int i = 0; i < possibleDesktopNames.length; i++) {
    if (!f.exists()) {
    f = new File(HOME_DIR + FILE_SEP + possibleDesktopNames);
    } else {
    break;
    }
    }
    if (!f.exists()) {
    return false;
    } else {
    path = f.getPath() + FILE_SEP + FOLDER;
    return true;
    }
    }

    /**
    * creates the file (including folders, if non-existant) and generates the BufferedWriter
    */
    private void createFile() throws Exception{
    int fileNb = 1;
    new File(path).mkdirs();
    File file = null;
    while (true) {
    file = new File(this.path + "/" + fileNb + " " + suffix + ".txt");
    if (file.exists()) {
    fileNb++;
    } else {
    break;
    }
    }
    if (!file.exists()) {
    file.createNewFile();
    }
    FileWriter fw = new FileWriter(file.getAbsoluteFile());
    bWriter = new BufferedWriter(fw);
    }

    /**
    * log a message. A message is only logged, if {@link #active} is set to true.
    * @param s the message to log
    */
    public void log(String s) throws Exception {
    if (this.active) {
    bWriter.append("\n" + s);
    }
    }

    /**
    * log an exception. As in {@link #log(String)} the exception is only logged, if {@link #active} is set to true.
    * @param description the description / additional text to log
    * @param e the exception to log
    * @param printStackTrace print the exceptions stack trace?
    */
    public void log(String description, Exception e, boolean printStackTrace) throws Exception {
    if (this.active) {
    if (printStackTrace) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    e.printStackTrace(pw);
    this.log(description + "\t" + e.toString() + "\n" + sw.toString());
    } else {
    this.log(description + "\t" + e.toString());
    }
    }
    }

    /**
    * save the logger. This closes the {@link #bWriter}.
    */
    public void save() throws Exception{
    if (bWriter != null) {
    bWriter.close();
    }
    }

    public static void main(String[] args) {
    try {
    Logger logger = new Logger("","description");
    logger.activate();
    logger.log("test123");
    logger.disable();
    logger.log("this should not appear in the logger file!");
    logger.activate();
    logger.log("exception only", new Exception("test exception"), false);
    logger.log("exception with stacktrace", new Exception("stack trace exception"), true);
    logger.disable();
    logger.log("this should not appear in the logger file!");
    logger.save();
    Logger mutedLogger = new Logger("", "muted Logger");
    logger.log("this shouldn't appear!!!");
    logger.log("this shouldn't appear!!!");
    logger.save();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

  • Options
    Marco_BoeckMarco_Boeck Administrator, Moderator, Employee, Member, University Professor Posts: 1,995 RM Engineering
    Hi,

    you will need to add your .jar file to the classpath of RapidMiner. You can either manipulate the .bat start script and add your .jar to the -classpath attribute (probably the easiest way), or you could extract the rapidminer.jar with a zip program of your choice, edit the /META-INF/MANIFEST.MF file by adding the name of your .jar to the list of .jar files in the classpath attribute already present and then rezip everything up into the rapidminer.jar again.

    Regards,
    Marco
  • Options
    elnecesarioelnecesario Member Posts: 5 Contributor II
    Hi Marco,

    thanks for your help. I tried the hard way with extracting, adapting the MANIFEST.MF and putting it all back together but didn't manage to do so...after that I had to install RM again. With this new RapidMiner the .bat scripts in the script folder are working again but my .jar is still not recognized in the script operator....
    I didn't need to adapt the .bat files because it adds all .jar files in the lib folder to the classpath...at least I think so. I added an echo for the RAPIDMINER_LIBRARIES variable to check if my jar appears in it and it does. You can see this in the log file I created by running the .bat file via cmd (the classpath in the .bar file is later set to: set COMPLETE_CLASSPATH=%RAPIDMINER_CLASSPATH%;%RAPIDMINER_LIBRARIES%):

    RAPIDMINER_HOME is not set. Trying the directory 'C:\Program Files\Rapid-I\RapidMiner5\scripts\..'...
    Using local jre: C:\Program Files\Rapid-I\RapidMiner5\scripts\..\jre\bin\java.exe...
    RAPIDMINER_LIBRARIES = ;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\bcmail.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\bcprov.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\blas.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\collections-generic.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\colt.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\commons-codec-1.4.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\commons-collections.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\commons-httpclient-3.1.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\commons-lang-2.4.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\commons-logging-1.1.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\concurrent.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\dailab.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\dom4j-1.6.1.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\encog.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\gentlyWEB.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\glazedlists.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\groovy-all-1.7.7.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\groovy-all.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\itextpdf-5.3.3.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\ivy-2.2.0.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jama.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jcommon.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jdom.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jep.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jfreechart.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jh.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jmathplot.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\joone-engine.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jugpreview.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jung-algorithms.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jung-api.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jung-graph-impl.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jung-visualization.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\junit.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jwnl.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\jxl.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\kdb.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\launcher.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\looks.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\mail.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\microba.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\poi-3.8-20120326.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\poi-excelant-3.8-20120326.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\poi-ooxml-3.8-20120326.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\poi-ooxml-schemas-3.8-20120326.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\poi-scratchpad-3.8-20120326.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\rapidminer.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\rm_doc.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\rome.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\rsyntaxtextarea.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\SassyReader-0.5.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\slf4j-api-1.6.4.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\slf4j-simple-1.6.4.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\swingx-all-1.6.4.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\vldocking.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\ws-commons-util-1.0.2.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\xmlbeans-2.3.0.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\xmlpull.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\xmlrpc-client-3.1.3.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\xmlrpc-common-3.1.3.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\xpp3.jar;C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\xstream.jar
    Starting RapidMiner from 'C:\Program Files\Rapid-I\RapidMiner5\scripts\..' using classes from 'C:\Program Files\Rapid-I\RapidMiner5\scripts\..\lib\rapidminer.jar'...
    Creating file "C:\Users\admin\AppData\Roaming\check_rm_java_version"
    Java Version: 1.7.0_11
    Removing file "C:\Users\admin\AppData\Roaming\check_rm_java_version"
    Starting in multicore mode with G1 garbage collector...
    exit=0

    the jar-file I want to add is called dailab.jar. So whatelse can I try to get the .jar file available in the script operator? Or is it wrong to just import the package I defined for my class I want to use?

    Regards,
    elnecesario
  • Options
    Marco_BoeckMarco_Boeck Administrator, Moderator, Employee, Member, University Professor Posts: 1,995 RM Engineering
    Hi,

    the jar seems to be available at runtime, so now I'd like to see the xml of your process which contains the Execute Script operator.

    Regards,
    Marco
  • Options
    elnecesarioelnecesario Member Posts: 5 Contributor II
    Hi,

    here the xml:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <process version="5.3.015">
      <context>
        <input/>
        <output/>
        <macros/>
      </context>
      <operator activated="true" class="process" compatibility="5.3.015" expanded="true" name="Process">
        <process expanded="true">
          <operator activated="true" class="execute_script" compatibility="5.3.015" expanded="true" height="60" name="execute script" width="90" x="179" y="75">
            <parameter key="script" value="import com.rapidminer.tools.Ontology;&#10;import de.dailab.ml.util.Logger;&#10;&#10;/**&#10; * the Main class, executing everything.&#10; */&#10;public class Main {&#10;&#9;ExampleSet exampleSet;&#10;&#9;Logger logger;&#10;&#10;&#9;/**&#10;&#9; * the constructor.&#10;&#9; * @param input the ExampleSet, usually given by the operators port. It can be retrieved by calling input.&#10;&#9; */&#10;&#9;public Main(ExampleSet input) {&#10;&#9;&#9;this.exampleSet = input;&#10;&#9;&#9;this.logger = new Logger(&quot;&quot;,&quot;remove questionmark-values&quot;);&#10;&#9;&#9;this.logger.activate();&#10;&#9;}&#10;&#10;&#9;/**&#10;&#9; * do the work&#10;&#9; */&#10;&#9;public void doWork() {&#10;&#9;&#9;logger.log(&quot;test1&quot;);&#10;&#9;&#9;logger.log(&quot;test2&quot;);&#10;&#9;&#9;logger.log(&quot;test3&quot;);&#10;&#9;&#9;logger.log(&quot;test4&quot;);&#10;&#9;&#9;logger.log(&quot;test5&quot;);&#10;&#9;&#9;logger.log(&quot;test6&quot;);&#10;&#9;}&#10;&#10;&#9;/**&#10;&#9; * get the results.&#10;&#9; * @return the ExampleSet, holding all data&#10;&#9; */&#10;&#9;public ExampleSet getResult() {&#10;&#9;&#9;return this.exampleSet;&#10;&#9;}&#10;}&#10;&#10;&#10;Main main = new Main(input[0]);&#10;main.doWork();&#10;return main.getResult();"/>
          </operator>
          <portSpacing port="source_input 1" spacing="0"/>
          <portSpacing port="sink_result 1" spacing="0"/>
        </process>
      </operator>
    </process>
    and here the error message that pops up:

    https://www.dropbox.com/sh/dhd4t4qvsbkm3cy/AACg4qUSeCc0NXwzDKUBXvgia

    image


    Regards,
    elnecesario
  • Options
    Marco_BoeckMarco_Boeck Administrator, Moderator, Employee, Member, University Professor Posts: 1,995 RM Engineering
    Hi,

    the error message and the code you posted earlier do not match, they show the same class in two different packages. I assume the code example is no longer up to date and the package structure now matches in the .jar and in the script import statement?

    Regards,
    Marco
  • Options
    elnecesarioelnecesario Member Posts: 5 Contributor II
    Hi Marco,

    yes you are right, I changed the package name, sorry....
    here is the up-to-date dailab.jar:
    https://www.dropbox.com/s/7fay3keet3fnwhi/dailab.jar


    btw.... how can I upload files to the forum instead of linking to my dropbox? One day I may delete the files in my dropbox and than my posts may not be as helpfull anymore to other people....


    Regards,
    elnecesario
Sign In or Register to comment.