I'm writing a Java ME application that uses iText to read PDF. When I write my code in standard Java including the iText libraries in the class-path, the application runs. However if I move the code into a java mobile application including the iText libraries in the class-path there is an error during compiling that says
error: cannot access URL
PdfReader reader = new PdfReader(pdfPath);
class file for java.net.URL not found
My problem is that I need a work around to read the PDF file. I've tried adding rt.jar as a library into my code which is the package that contains java.io but it is too big to be compiled. Please help me find a work around. My code is here
package PDFreaderpackage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
import com.sun.lwuit.Display;
import com.sun.lwuit.Form;
import com.sun.lwuit.TextArea;
import javax.microedition.midlet.MIDlet;
public class Midlet extends MIDlet {
Form displayForm;
TextArea pdfText;
private String bookcontent;
public static String INPUTFILE = "c:/test.pdf";
public static int pageNumber = 1;
public void startApp() {
Display.init(this);
this.bookcontent = readPDF(INPUTFILE, pageNumber);
pdfText = new TextArea(bookcontent);
displayForm = new Form("Works");
displayForm.addComponent(pdfText);
displayForm.show();
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public String readPDF(String pdfPath, int pageNumber) {
try {
PdfReader reader = new PdfReader(pdfPath);
this.bookcontent = PdfTextExtractor.getTextFromPage(reader, pageNumber);
} catch (Exception e) {
System.out.println(e);
}
return bookcontent;
}
}
These classes aren't available on a mobile device and JavaME doesn't support Java 5 features. What you are trying to do is somewhat impractical. Codename One allows some more classes thanks to bytecode processing but even then this isn't close to a complete rt.jar.
If you have the time, you can try and create a Java ME compliant version of iText, but to properly open a PDF the library must use some form of Random Access File because of the xref table at the end of the file. This sort of file connection is not available in Java ME.
What the library can do is to fully load the PDF to memory, which is highly dependent on the file size and the handset memory available.
You better create a Web Service to receive your PDF and return, for example, PNG images from it.
Related
Is it possible to use tinify compression API in Android? I've implemented all the required stuff, but the app is crashing all the time. Here's the code:
File photo = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), imageName()+".jpg");
try {
Log.d("TINY", photo.getAbsolutePath());
Source source = Tinify.fromFile(photo.getAbsolutePath());
} catch (IOException e) {
Log.e("TINY", e.getMessage());
e.printStackTrace();
}
A am getting the following error:
FATAL EXCEPTION: main
java.lang.NoClassDefFoundError: java.nio.file.Paths
If it's not possible, are there any other good APIs for image compression for Android?
It's not possible as-is. Note that java.nio.file.Paths was added in Java 7, but Android still only fully supports Java 6, with some Java 7 language features if you are using a specific buildToolsVersion and minSdkVersion. Also see the Things that don't Work section at the Java7-on-Android project page.
Like the answer to Android import java.nio.file.Files; cannot be resolved states, it's not possible to use classes from the java.nio.file package.
But that doesn't necessarily mean you can't use the Tinify API. If you're able to provide all other referenced classes, you can use it with a few modifications, since it's open source and there are only two occurrences of Files and Paths you need to rewrite:
Result.java
public void toFile(final String path) throws IOException {
Files.write(Paths.get(path), toBuffer());
}
Source.java
public static Source fromFile(final String path) throws IOException {
return fromBuffer(Files.readAllBytes(Paths.get(path)));
}
I've looked around on stack overflow, and a few other sites, but I can't really find anything helpful. I need to have code that can play an audio file that is inside the same as my Class.java file. In other words, I need it to play a file without typing in the exact location of the file, llike if I was sending it to a friend. Here is what I have:
import java.applet.*;
import java.net.*;
public class MainClass extends Applet {
public void init() {
try {
AudioClip clip = Applet.newAudioClip(
new URL(“file://C:/sound.wav”));
clip.play();
} catch (MalformedURLException murle) {
murle.printStackTrace();
}
}
But I can't get it to play from just anywhere, only that specific folder. Is there a way to do this without typing "URL" before the file location?
Change your URL declaration , change "file://C:/sound.wav" to "file:C:/sound.wav"
import java.applet.*;
import java.net.*;
public class MainClass {
public static void main(String[] args) {
try {
AudioClip clip = Applet.newAudioClip(
new URL("file:C:/sound.wav"));
clip.play();
} catch (MalformedURLException murle) {
murle.printStackTrace();
}}}
*I had tested it and working great under NetBeans IDE
I believe Applet.audioClip() is intended for use inside Applets, rather than a desktop app. One of the limitations is that you can only use a URL to locate the sound resource. On the other hand the Java Sound API is more versatile. It allows you to locate the sound resource with a File object as well as many other options.
You also need to figure out how to refer to your file. In particular, if you want to use a relative path, you need to figure out what base path your environment will start from. Embedding resources (images, sound bits, etc) into a Java project then use those resources will give you more details about how to resolve this issue.
I'm trying to use Apache POI within XPages to create a Word document. I have a button which executes some SSJS to call a method from a Java class. However, as soon as the Java code tries to instantiate a new object, an error occurs. Here is my code:
SSJS:
importPackage(TESTPackage);
var jce:WordReferenceTest = new WordReferenceTest();
jce.newWordDoc();
Java:
package TESTPackage;
import org.apache.poi.xwpf.usermodel.*;
public class WordReferenceTest {
public void newWordDoc() {
try {
XWPFDocument doc = new XWPFDocument();
} catch (Exception e) {
e.printStackTrace();
}
}
}
I have IBM Notes 9.0 and have imported all the Apache POI JAR files as JARS directly into my database.
The error message I get is
Error 500
HTTP Web Server: Command Not Handled Exception
On OpenNTF there is OpenNTF Essentials. It contains everything that you need to handle word documents. Try to use that. You might run foul of security or logging.
Reuse what is there already.
I'm using Lotus Domino server 8.5.2. Using Java scheduled agents, I can extract the attachments of several Lotus Domino Documents in to the file system (win 32). The Idea is that after extraction I need add some metadata to the files and upload the files to another system.
Does someone knows, or can give me a few tips (preferably using Java) of how I can write some metadata to the extracted files? I need add some keywords, change the author, and so on. I understand Lotus Domino 8.5.2 supports Java 6
thank you!
Alex.
According to this answer, Java 7 has a native ability to manipulate Windows metadata but Java 6 does not.
It does say that you can use Java Native Access (JNA) to make calls to native DLLs, which means you should be able to use dsofile.dll to manipulate the metadata. Example from here of using JNA to access the "puts" function from msvcrt.dll (couldn't find any examples specific to dsofile.dll):
Interface
package CInterface;
import com.sun.jna.Library;
public interface CInterface extends Library
{
public int puts(String str);
}
Sample class
// JNA Demo. Scriptol.com
package CInterface;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
public class hello
{
public static void main(String[] args)
{
String mytext = "Hello World!";
if (args.length != 1)
{
System.err.println("You can enter your own text between quotes...");
System.err.println("Syntax: java -jar /jna/dist/demo.jar \"myowntext\"");
}
else
mytext = args[0];
// Library is c for unix and msvcrt for windows
String libName = "c";
if (System.getProperty("os.name").contains("Windows"))
{
libName = "msvcrt";
}
// Loading dynamically the library
CInterface demo = (CInterface) Native.loadLibrary(libName, CInterface.class);
demo.puts(mytext);
}
}
I am trying to print out all of the capture devices that are supported using the #getDeviceList() method in the CaptureDeviceManager class and the returned Vector has a size of 0.
Why is that? I have a webcam that works - so there should be at least one. I am running Mac OS X Lion - using JMF 2.1.1e.
Thanks!
CaptureDeviceManager.getDeviceList(Format format) does not detect devices. Instead it reads from the JMF registry which is the jmf.properties file. It searches for the jmf.properties file in the classpath.
If your JMF install has succeeded, then the classpath would have been configured to include all the relevant JMF jars and directories. The JMF install comes with a jmf.properties file included in the 'lib' folder under the JMF installation directory. This means the jmf.properties would be located by JMStudio and you would usually see the JMStudio application executing correctly. (If your JMF install is under 'C:\Program Files', then run as administrator to get around UAC)
When you create your own application to detect the devices, the problem you described above might occur. I have seen a few questions related to the same problem. This is because your application's classpath might be different and might not include the environment classpath. Check out your IDE's properties here. The problem is that CaptureDeviceManager cannot find the jmf.properties file because it is not there.
As you have found out correctly, you can copy the jmf.properties file from the JMF installation folder. It would contain the correct device list since JMF detects it during the install (Check it out just to make sure anyway).
If you want do device detection yourself, then create an empty jmf.properties file and put it somewhere in your classpath (it might throw a java.io.EOFException initially during execution but that's properly handled by the JMF classes). Then use the following code for detecting webcams...
import javax.media.*;
import java.util.*;
public static void main(String[] args) {
VFWAuto vfwObj = new VFWAuto();
Vector devices = CaptureDeviceManager.getDeviceList(null);
Enumeration deviceEnum = devices.elements();
System.out.println("Device count : " + devices.size());
while (deviceEnum.hasMoreElements()) {
CaptureDeviceInfo cdi = (CaptureDeviceInfo) deviceEnum.nextElement();
System.out.println("Device : " + cdi.getName());
}
}
The code for the VFWAuto class is given below. This is part of the JMStudio source code. You can get a good idea on how the devices are detected and recorded in the registry. Put both classes in the same package when you test. Disregard the main method in the VFWAuto class.
import com.sun.media.protocol.vfw.VFWCapture;
import java.util.*;
import javax.media.*;
public class VFWAuto {
public VFWAuto() {
Vector devices = (Vector) CaptureDeviceManager.getDeviceList(null).clone();
Enumeration enum = devices.elements();
while (enum.hasMoreElements()) {
CaptureDeviceInfo cdi = (CaptureDeviceInfo) enum.nextElement();
String name = cdi.getName();
if (name.startsWith("vfw:"))
CaptureDeviceManager.removeDevice(cdi);
}
int nDevices = 0;
for (int i = 0; i < 10; i++) {
String name = VFWCapture.capGetDriverDescriptionName(i);
if (name != null && name.length() > 1) {
System.err.println("Found device " + name);
System.err.println("Querying device. Please wait...");
com.sun.media.protocol.vfw.VFWSourceStream.autoDetect(i);
nDevices++;
}
}
}
public static void main(String [] args) {
VFWAuto a = new VFWAuto();
System.exit(0);
}
}
Assuming you are on a Windows platform and you have a working web-cam, then this code should detect the device and populate the jmf.properties file. On the next run you can also comment out the VFWAuto section and it's object references and you can see that CaptureDeviceManager reads from the jmf.properties file.
The VFWAuto class is part of jmf.jar. You can also see the DirectSoundAuto and JavaSoundAuto classes for detecting audio devices in the JMStudio sample source code. Try it out the same way as you did for VFWAuto.
My configuration was Windows 7 64 bit + JMF 2.1.1e windows performance pack + a web-cam.
I had the same issue and I solved by invoking flush() on my ObjectInputStream object.
According to the API documentation for ObjectInputStream's constructor:
The stream header containing the magic number and version number are read from the stream and verified. This method will block until the corresponding ObjectOutputStream has written and flushed the header.
This is a very important point to be aware of when trying to send objects in both directions over a socket because opening the streams in the wrong order will cause deadlock.
Consider for example what would happen if both client and server tried to construct an ObjectInputStream from a socket's input stream, prior to either constructing the corresponding ObjectOutputStream. The ObjectInputStream constructor on the client would block, waiting for the magic number and version number to arrive over the connection, while at the same time the ObjectInputStream constructor on the server side would also block for the same reason. Hence, deadlock.
Because of this, you should always make it a practice in your code to open the ObjectOutputStream and flush it first, before you open the ObjectInputStream. The ObjectOutputStream constructor will not block, and invoking flush() will force the magic number and version number to travel over the wire. If you follow this practice in both your client and server, you shouldn't have a problem with deadlock.
Credit goes to Tim Rohaly and his explanation here.
Before calling CaptureDeviceManager.getDeviceList(), the available devices must be loaded into the memory first.
You can do it manually by running JMFRegistry after installing JMF.
or do it programmatically with the help of the extension library FMJ (Free Media in Java). Here is the code:
import java.lang.reflect.Field;
import java.util.Vector;
import javax.media.*;
import javax.media.format.RGBFormat;
import net.sf.fmj.media.cdp.GlobalCaptureDevicePlugger;
public class FMJSandbox {
static {
System.setProperty("java.library.path", "D:/fmj-sf/native/win32-x86/");
try {
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
GlobalCaptureDevicePlugger.addCaptureDevices();
Vector deviceInfo = CaptureDeviceManager.getDeviceList(new RGBFormat());
System.out.println(deviceInfo.size());
for (Object obj : deviceInfo ) {
System.out.println(obj);
}
}
}
Here is the output:
USB2.0 Camera : civil:\\?\usb#vid_5986&pid_02d3&mi_00#7&584a19f&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global
RGB, -1-bit, Masks=-1:-1:-1, PixelStride=-1, LineStride=-1