I would like to run the main method of a java class by using #Grab so that requirements are taken care of automatically. More specifically I would like to run the pdfbox example https://github.com/apache/pdfbox/blob/trunk/examples/src/main/java/org/apache/pdfbox/examples/util/RemoveAllText.java
I wrote the following groovy script
#!/usr/bin/env groovy
#Grab('org.apache.pdfbox:pdfbox-examples:2.0.20')
import org.apache.pdfbox.examples.util.RemoveAllText
RemoveAllText.main(args)
The #Grab, import and execution of main seems to work. But the main seems to recall itself repeatedly thus failing with a StackOverflowError as below.
Caught: java.lang.StackOverflowError
java.lang.StackOverflowError
at RemoveAllText.main(RemoveAllText.groovy)
at RemoveAllText$main.call(Unknown Source)
at RemoveAllText.run(RemoveAllText.groovy:5)
at RemoveAllText.main(RemoveAllText.groovy)
...
I am new to groovy so I am not sure what I am doing wrong. Is what I am trying to do possible? If it is possible, how would it be done?
To make the example fully reproducible I get the above error when I use the pdf found at https://github.com/mozilla/pdf.js/raw/v2.4.456/examples/learning/helloworld.pdf and using groovy version 2.4.16 installed using the default repositories in Ubuntu 18.04. The command run would be
groovy RemoveAllText.groovy helloworld.pdf helloworld_out.pdf
If I manually download the required jar files and I run
java -cp pdfbox-2.0.20.jar:commons-logging-1.2.jar:pdfbox-examples-2.0.20.jar org.apache.pdfbox.examples.util.RemoveAllText helloworld.pdf helloworld_out.pdf
it works without problem.
Rename your script from RemoveAllText.groovy to something else and everything should be fine.
Problem that your groovy script produces the same class name as Apache class.
Related
I have a feature that execute a function from a Java class. So for this reason I use this command to get the class and create a new instance:
When I run this feature with maven (mvn test -Dtest...) everything is okay. The problem is when I run this feature with karate standalone jar, karate can't find the RCNUtils class.
Error:
org.graalvm.polyglot.PolyglotException: TypeError: Access to host class utilities.RCNUtils is not allowed or does not exist.
GraalJS error: https://github.com/oracle/graaljs/blob/master/docs/user/FAQ.md#typeerror-access-to-host-class-commyexamplemyclass-is-not-allowed-or-does-not-exist
I think it's a classpath problem but I have tried with a lot of differents paths and commands to execute the jar, and nothing works.
I don't know if this is a known issue or if there is a karate example using utilities classes and executed with karate.jar
I tested this problem with differents Karate versions. Actually I'm using Karate 1.1.0
Some of the options I have tried with no results:
Use -w / --workdir param to change working directory with no results
Use java -cp instead of java -jar to set classpath following:
Unable to use read('classpath:') when running tests with standalone karate.jar
Use -Dkarate.config.dir param
Note: I don't think it's a security problem because if I try to get "RCNUtils.java" file with "karate.read()" or "read()" in the same feature, it works. I think because I can put the path to the file. The problem is that I can't put the path to java class in "Java.type()" method
Same error here: Executing Karate jar with mock using external library Spring Framework
Thanks in advance.
I have a Netbeans project of some Java code I wrote many years ago. I am doing a new project in python now, but I have a Java class in my old project that has some handy MIDI code that I would like to use since I have so far been unable to easily translate to python.
I used pip to install JPype, used Netbeans to build the class I need, and moved the .class file into the same directory as my python file. Here is an abridged part of my python code to call the Java class, which is called "SoundTester" and was in a package called "soundsynthesis".
from jpype import startJVM, shutdownJVM, java, addClassPath, JClass, JInt
import jpype.imports
startJVM(convertStrings=False)
try:
pass # Not sure why we need a pass here
tester = JClass('soundsynthesis/SoundTester')
except Exception as e:
print(f"Exception: {e}")
shutdownJVM()
The result is
Exception: java.lang.NoClassDefFoundError: soundsynthesis/SoundTester
Note that if I change soundsynthesis/SoundTester to just SoundTester, I get this slightly different exception:
Exception: java.lang.NoClassDefFoundError: SoundTester (wrong name: soundsynthesis/SoundTester)
I'm thinking that the issue may be due to me moving the .class files out of the Netbeans project and into my working directory, but I don't know how to resolve that. I also tried moving the java files into my desired directory and just using javac to build them.
I have ensured that my version of python and the jdk are both 64-bit, as that was a similar question's issue.
This is an issue with the path specification. It is true that JNI usually refers to classes using the slash notation. However, in this case JClass calls the Java Class.forName() method which requires dot notation rather than JNI. Thus the solution to this issue is to use JClass('soundsynthesis.SoundTester').
Here is an example using the test harness in jpype.
import jpype
jpype.startJVM(classpath=['test/classes'], convertStrings=False)
j = jpype.JClass('jpype.common.Fixture') # success
j = jpype.JClass('jpype/common/Fixture') # fails
In general, JPype uses the notations that are found in Java itself rather than those imposed by JNI. For further examples, please see the section "Import a class without tld" in the quick guide.
I solved the issue. Perhaps not the most elegant solution, but I modified the Java classes so they instead were not in any package (or rather they were in the default package) and then moved them to my python working directory and built them with javac there.
Once I had .class files of my java classes, I could call
tester = JClass('SoundTester') with no problem whatsoever.
Hope this helps someone else.
I am building a Spark application that make use of some feature already developed in Ruby.
I made the choice to invoke the Ruby part from my Scala main by defining MyProxy class in ruby and compiling with JRuby.
I can then use MyProxy to invoke the rest of the Ruby code that stay in scripts. Foremost reason is that I was unable to compile them with JRuby, probably because they are too dynamic:
## myProxy.rb -> compiled into myProxy.class
## jrubyc --javac myProxy.rb
require 'java'
java_package 'ruby.proxy'
require_relative 'some.rb'
class MyProxy
def self.invoke_script()
... ## invoke some other ruby in script that are note compiled by jrubyc
end
end
and the Scala Main:
object myRun extends App {
val something = MyProxy.invoke_script()
...
}
At runtime the flow looke like this:
Main.class (scala) -> call myProxy.class (compiled ruby of myProxy.rb) -> call function in script.rb
It works, and I was able to make a runnable jar for the Scala and compiled ruby part. But when I am running it: java -jar myApp.jar,
it still need to access my myProxy.rb file and, of course, all other scrips.rb.
So I need a copy of all my ruby scripts in the working directory when executing this command.
Ideally I would like to include all the ruby scripts in the myApp.jar as well, and be able to deploy easily deploy on a spark cluster.
Is this possible, and how?
I have looked at warbler and rawr. However, I don't see how these tools can help me in this mixed environment (main in Java, some part compiled ruby, some part pure scripts).
Any help appreciated!
As stated in the jruby documentation, packaging ruby scripts in a jar, should be has simple as including them in the .jar (sic):
Everything in the Java classpath is considered to be a load path entry, so .rb scripts, for example, contained in JAR files, are loadable.
It wasn't working in my case, because I was using require_relative in my script, which doesn't seem to work properly in recent release of JRuby. Replacing require_relative with require made it works with scripts embedded in myApp.jar.
Moreover using require_relative 'toto' in titi.rb was triggering an error of titi.rb script not found, which was misleading since it was titi.rb which was being executed.
I have written a Java Class for use in JMeter, packaged the project as a .jar file and moved that file into the lib/ext folder in the jmeter directory. I have seen documentation on how to proceed but they give contradictory answers.
The first way is to use the BeanShell Sampler to import my package and class, create an object of the class and run the methods that way. I have used this method using example classes with more simple file structures than that of class I want to run. The example classes work with the following BeanShell script.
import tools.JmeterTools;
JmeterTools jt = new JmeterTools();
jt.foo();
When I try to use this method for the class I want to run, it states that the variable declaration is an error and the Class cannot be found. I assume this is because I do not understand what to import exactly, as the file structure in my project is a little odd.
The second uses the BeanShell PreProcessor to add the jar to the class path. This method I have not been able to get to work at all, but have read many accounts of others finding success. It works as follows:
addClassPath("directory path to jar\lib\ext\foo.jar");
JMeterTest jtm = new JMeterTest();
jmt.test();
Would anyone have any knowledge of which way would work better or any ideas on how to fix the import?
The import I have been using in the BeanShell script is the following:
import client.JMeterTest;
The package line at the top of my class is the following
import com.x.foo.client;
You need to have your jar file in JMETER_HOME/lib folder.
lib/ext is for JMeter extensions/plugins etc.
Once you have placed your jar, you might have to restart JMeter.
Running external classes from Beanshell should work fine given the following preconditions met
Your test with dependencies is located in JMeter classpath.
JMeter restart is required to pick new libraries up
You need to provide full package name plus full class name (or wildcard) for import.
Either
import com.x.foo.client.JMeterTest;
or
import com.x.foo.client.*;
And finally it is recommended to use JSR223 Sampler and use "groovy" as a language. Beanshell interpreter has severe performance issues so use it for something very "light" like variable amendment, converting variable to property, etc. For generating the real load use JSR223 and groovy as it implements Compilable interface and hence you can achieve performance similar to native Java code. See Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For! guide for detailed explanation, benchmarking and instructions on installation of groovy scripting engine support.
For anyone who has this issue in the future. The answers given by others are correct. It wasn't working for me because I had forgotten that Maven does not package files in the test directory when a jar is made.
This link may help if anyone ever does this in the future.
Generate test-jar along with jar file in test package
I am using Selenium to do tests on some html. I was using java under Eclipse and run test by Junit. And everything was fine. But I got problems when I started use command line (javac/java at Dos prompt) to compile/run the test.
For this java project, I have a bunch of classes, each one represents one test while each each class sits in its own java file. And All these files are under one package/folder called "testSuite". Each test file will import a bunch of jar files. And they also import Global class from another
The problems, the compile was ok. but I make it run. I compiled global.java first then compiled PolicyFilter.java and then try to run the class, below is what I got:
Exception in thread "main" java.lang.NoClassDefFoundError: \testsuite\PolicyFilter (wrong name: testSuite/PolicyFilter)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
Please use java -cp requiredClassfiles/folders/jars classToExecute.
I hope you have Selenium RC Jar available and started it using command java -jar selenium-server-standalone-<version-number>.jar.
Make sure that you put the annotation #Test on the test, clean the folder target in project folder and then restart the eclipse.
Hope it works :))