I'm attempting to use JPype to call Apache Pdfbox from Python, and am having some difficulty actually importing the classes. It doesn't seem to be able to read them from the jar file in the class path.
from jpype import java, startJVM, shutdownJVM, JPackage, JClass, getDefaultJVMPath, nio
import sys, os, codecs
pdfbox_lib = "lib/pdfbox-1.6.0.jar"
classpath = '-Djava.class.path=' + pdfbox_lib + os.pathsep + '.'
startJVM(getDefaultJVMPath(), '-Xmx512m', classpath)
stream = java.io.FileInputStream(java.io.File("test.pdf"))
pdfparser = JPackage('org.apache.pdfbox.pdfparser')
parser = JClass('org.apache.pdfbox.pdfparser.PDFParser')
At this point, the script errors out with the following:
java.lang.ExceptionPyRaisable: java.lang.Exception: Class org.apache.pdfbox.pdfparser.PDFParser not found
I'm running on Linux with Python 2.7, and I know there's nothing wrong with the JPype installation (if there were, the stream declaration would error out). I've also tried various permutations of the class path statement and the JPackage/JClass statements, and nothing seems to matter. Any suggestions would be greatly appreciated!
I figured it out. Three additional jars need to be added to the class path: fontbox-x.x.x.jar, jempbox-x.x.x.jar, and commons-logging.jar.
Related
I recently used decode_qr from this FEX submission to decode my QR code. It ran quite well one or two weeks ago, but today it generate an error for me:
Undefined function or variable 'BufferedImageLuminanceSource'
Error in decode_qr (line 34);
source = BufferedImageLuminanceSource(jig);
I just checked the zxing repository and found that some files were updated several days ago. So I guess the path of some imported file from the package has been changed.
Here is the importing code from the decode_qr function:
import com.google.zxing.qrcode.*;
import com.google.zxing.client.j2se.*;
import com.google.zxing.*;
import com.google.zxing.common.*;
import com.google.zxing.Result.*;
How can I get it to work again? Do I need to change the import paths?
Here's what I did to get it to work (Win 10 x64, R2017b, ZXing 3.3.1):
Downloaded the latest prebuilt .jar artifacts from Sonatype:
core.
javase.
Added the files to my dynamic java classpath using javaaddpath:
javaaddpath('G:\core-3.3.1.jar');
javaaddpath('G:\javase-3.3.1.jar');
% Verify using: javaclasspath('-dynamic');
Note:
To add folders to the static path, which MATLAB loads at startup, create a javaclasspath.txt file, as described in Static Path.
Generated some example QR code using unitag.io:
Tried to decode it using Lior Shapira's decode_qr:
>> out = decode_qr(qr)
out =
'https://stackoverflow.com/users/3372061/dev-il'
Full code:
function out = q47223578()
javaaddpath('G:\core-3.3.1.jar');
javaaddpath('G:\javase-3.3.1.jar');
% Verify using: javaclasspath('-dynamic');
qr = imread('https://i.stack.imgur.com/mA4eP.png');
out = decode_qr(qr);
I am adding jar files to my jruby code in the .rb file
I put the following:
import 'java'
import 'weather.jar'
import 'weatherStatus.WeatherStatus' #this is the package and class
Now I have classes in weather.jar that I need to use here but it keeps giving me errors. I don't know how to convert the following java lines to jruby and everytime I try something from the tutorials, it give me errors.
The following command lines are from java and I want to include them in my jruby file:
sunnyDay var1 = null;
var1 = new sunnyDay(var2, var3);
String var4 = var1.TimeOfDay(var5);
sunnyDay is from package called weatherStatus
How can I do that in Jruby?
I suggest you thoroughly read the following two links to have a better understanding of using JRuby :)
https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby
https://github.com/jruby/jruby/wiki/DirectJRubyEmbedding
JPype is an amazing project since I allows to instantiate a JVM directly from Python.
Unfortunately, I got stuck in the first baby steps.
I have A.java source code (located in C:\tmp folder):
class A {
public A() {
super();
}
public String sayHi() {
return("Hello");
}
}
Which was compiled to a class, using: javac A.java
Thus, A.class is located in C:\tmp folder.
I have the following Python source code:
import os
import jpype
jpype.startJVM(jpype.getDefaultJVMPath(), '-ea', '-Djava.class.path=c:\\tmp')
A = jpype.JClass("A")
a = A()
print a.sayHi()
jpype.shutdownJVM()
When I run it, I get the error below:
C:\tmp>jpype_test.py
Traceback (most recent call last):
File "C:\tmp\jpype_test.py", line 10, in <module>
A = jpype.JClass("A")
File "C:\Python27\lib\site-packages\jpype\_jclass.py", line 54, in JClass
raise _RUNTIMEEXCEPTION.PYEXC("Class %s not found" % name)
jpype._jexception.ExceptionPyRaisable: java.lang.Exception: Class A not found
Since I can't find the A class, it is probably an issue related to CLASSPATH, but I can't realize what I am doing wrong.
Any clues?
EDIT 1:
The problem persists. But, just to add to my question, if I use native java libraries, like: java.util, the code runs WITHOUT errors. For example, the code below works:
import jpype
jpype.startJVM(jpype.getDefaultJVMPath())
util = jpype.JPackage("java.util")
al = util.ArrayList()
al.add(1)
al.add(2)
print al.size()
jpype.shutdownJVM()
And returns 2.
EDIT 2:
Issue solved, see answer below...
I solved the problem and I would let the answer here for the records.
1) Nothing was wrong with the source code.
2) Problem was that my Python was 32 bits and my java sdk (including the javac bytecode compiler) was 64 bits. I uninstalled the java sdk and re-installed a 32bits version. Done! Solved!
Try to change your path like this:
jpype.startJVM(jpype.getDefaultJVMPath(), '-ea', '-Djava.class.path=c:\\tmp\')
I need to find the jar from a Java project that provides a certain logical Java package (e.g. com.example.functionality), but there are hundreds of them, and their names aren't particularly useful.
How to find out the mappings that are created between dirs/files/jars and packages/classes?
obj.getClass().getProtectionDomain().getCodeSource()
See: javadoc
You can do it in code:
Class myClass = Class.forName("com.example.functionality");
// eg. /com/example/functionality.class
String classfilePath = '/' + myClass.getName().replace(".", "/") + ".class";
URL location = myClass.getResource(classfilePath);
That URL will be the JAR file (or the class folder if it isn't in a jar).
Slightly hacky though - may not work for all classloaders.
For a one-off search, http://www.jarfinder.com/ is handy. It has in impressive index, which seems to know about everything in Maven Central as well as many other download sites around the web, and lets you search by class name to find which JARs contain that class.
I've been trying to use Matlab's javabuilder package under Windows XP, but I'm getting a strange error when trying to instantiate any javabuilder class. To illustrate the problem, I've created a simple program that prints the MCRROOT and PATH system variables (to check if they're correctly set) and tries to create a MWCharArray:
import com.mathworks.toolbox.javabuilder.*;
import com.mathworks.toolbox.javabuilder.internal.MCRConfiguration;
class Main
{
public static void main(String[] args)
{
System.out.println("MCRROOT: " + System.getenv("MCRROOT"));
System.out.println("PATH: " + System.getenv("PATH"));
System.out.println(MCRConfiguration.isInstalledMCR());
MWCharArray test = new MWCharArray("Test");
}
}
When I execute the program, the output is:
MCRROOT: C:\Program files\MATLAB\MATLAB Compiler Runtime\v710
PATH: C:\Program files\CollabNet Subversion Client;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program files\MATLAB\MATLAB Compiler Runtime\v710
false
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration.getMCRRoot(MCRConfiguration.java:77)
at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$ModuleDir.<clinit>(MCRConfiguration.java:51)
at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration.getModuleDir(MCRConfiguration.java:56)
at com.mathworks.toolbox.javabuilder.internal.MWMCR.<clinit>(MWMCR.java:1447)
at com.mathworks.toolbox.javabuilder.MWUtil.GetUnknownClassID(MWUtil.java:1258)
at com.mathworks.toolbox.javabuilder.MWClassID.<clinit>(MWClassID.java:41)
at com.mathworks.toolbox.javabuilder.MWCharArray.<init>(MWCharArray.java:75)
at Main.main(Main.java:11)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1937)
at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$MCRRoot.get(MCRConfiguration.java:70)
at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$MCRRoot.<clinit>(MCRConfiguration.java:72)
... 8 more
Java Result: 1
First of all, are MCRROOT's and PATH's values correct? I've tried google for finding out how to set MCRROOT, but there are conflicting results: some sources say that I should include de version dir, others say the opposite. Also, why is the isInstalledMCR method returning false? I've double-checked the MCR installation (and even uninstalled and installed it to be sure), so why isn't the library finding it?
Thanks on advance for any help!
Edit: I've also tried setting MCRROOT with no version string, and it also fails.
Just wild guessing! Java is messing around with strings, while your 'mcrroot' contains white spaces. I might change the mcr install path to something like C:\MATLAB\MATLABCompilerRuntime\v710, omitting any white spaces and special characters.
I've found the solution, so I'm post a self answer for future reference: Besides adding the javabuilder.jar to the program's classpath, you also have to add the path to the MCR's runtime libraries to the java.library.path JDK parameter.
My mistake was that, instead of setting the path as the path to the libraries at the MCR installation directory (On my case, C:\MATLAB\MCR\v710\runtime\win32), I copied the runtime directory to my project's dir and used it instead. It seems that the javabuilder library uses the java.library.path variable the guess the MCROOT, what would explain the weird "StringIndexOutOfBoundsException".