I have an applet that is executed in an HTML file that the user downloads and opens locally (i.e. file:// on the URL bar). This applet has a method that downloads a file from the web and stores it in a directory inside the directory where the applet is running. On my HTML file I call the function to download a file and it works but when I call it the second time, to download another file, I get a Error calling method on NPObject. I don't get any error on the Java side (I have the console open and it stays clean).
What can be the issue here? Thank you a lot for your help. Below, the code of the applet.
import java.security.*;
import java.io.*;
import java.nio.channels.*;
import java.net.*;
public class EPPenDrive extends java.applet.Applet {
public final static String baseURL = "http://localhost/data/documents/";
public String downloadFile(final String filename) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
URL finalURL = new URL(baseURL + filename);
ReadableByteChannel rbc = Channels.newChannel(finalURL.openStream());
URL appletDir = getCodeBase();
FileOutputStream fos = new FileOutputStream(appletDir.getPath() + "documents/"+ filename);
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
return 1;
} catch (Exception x) {
x.printStackTrace();
return null;
}
}
});
}
public void init() { }
public void stop() { }
}
I found the problem: the run() method would block if returning 1. I changed it to return null and now everything works. :)
Related
I am trying to upload a file into Azure Blob.
and I am trying to achieve through Upload in vaadin framework. Vaadin Version : 6.7.8
I am able to develop a code for uploading the file into azure blob.
My Problem Statement Lies below :
I have written a class UploadToBlob.java to upload a file into azure blob.
If I run the class UploadToBlob.java indivually (ran from eclipse run as java application), I am able to upload the file into azure blob.
If I create a object of the UploadToBlob class in my other class[ModifyComplaintComponent.java], storageAccount = CloudStorageAccount.parse(storageConnectionString); is not getting execute.
Below is the UploadToBlob.java code:
package com.---.trs.scms.ui.components;
import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.StorageCredentials;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
public class UploadToBlob {
public static void main(String[] args) {
try {
final String storageConnectionString = "DefaultEndpointsProtocol=https;AccountName=abcd;AccountKey=bmiA7+****==;EndpointSuffix=core.windows.net";
System.out.println("---I am getting called Main-1 ");
CloudStorageAccount storageAccount;
storageAccount = CloudStorageAccount.parse(storageConnectionString);
com.microsoft.azure.storage.blob.CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
CloudBlobContainer container = blobClient.getContainerReference("container2");
container.createIfNotExists();
String filePath = "C:\\Users\\----\\Desktop\\Timesheet - 19th Aug,2019.pdf";
com.microsoft.azure.storage.blob.CloudBlockBlob blob = container.getBlockBlobReference("Timesheet.pdf");
java.io.File source = new java.io.File(filePath);
java.io.FileInputStream fileInputStream = new java.io.FileInputStream(source);
blob.upload(fileInputStream, source.length());
} catch (Exception e) {
e.printStackTrace();
}
}
}
For now , I am passing manual file PATH as above to upload in azure blob, as I told above , this class is getting called till the line of code System.out.println("---I am getting called Main-1 ");
Here is the ModifyComplaintComponent code from where I am calling UploadToBlob.java:
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Upload;
public class ModifyComplaintComponent extends CustomComponent {
//other component code which I haven't pasted here
private Upload uploadnew;
try {
System.out.println("------Inside try block-----------");
UploadToBlob fileReceiver= new UploadToBlob ();
uploadnew = new Upload("Upload a file", fileReceiver);
uploadnew.setReceiver(fileReceiver);
uploadnew.addListener(fileReceiver);
System.out.println("------end of try block-----------");
} catch (Exception e) {
System.out.println("------catch block-----------");
e.printStackTrace();
}
HorizontalLayout hlayout = new HorizontalLayout();
hlayout.setSpacing(true);
hlayout.addComponent(uploadnew);
}
The Reason why I have given a manual file path in my UploadToBlob code is because I firstly wanted to make this code called from ModifyComplaintComponent class.
Secondly when I try to browse the file , and file gets selected but when I click on upload , I get NullPointerException On Vaadin Upload UI Part and even if i selected the file , UI says "no file choosen"
The challenge I am facing is If I run the Upload.java file individually I am able to upload static file into azure blob , but I wanted to browse and upload a file in vaadin framework into azure blob storage.
Firstly, Upload is a Component of Vaadin. You should not create your own Upload class.
Secondly, the public static main method is an entrance where your program starts. If you want to use a method of a class, you need to explicitly invoke it.
TheClassName.MethodName(...) // For static method
new TheClassName(...).MethodName(...) //For non-static method
Thirdly, I did some tests, the following is a successful sample. Two classes will be created:
Class UploadReceiver
This class implements the Receiver interface and some listeners.
import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import com.microsoft.azure.storage.blob.CloudBlockBlob;
import com.vaadin.ui.Upload;
import org.springframework.stereotype.Component;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
#Component
public class UploadReceiver implements Upload.Receiver, Upload.StartedListener, Upload.SucceededListener, Upload.ProgressListener {
// Storage account connection string.
public static String conn = "DefaultEndpointsProtocol=https;AccountName=stora***789;AccountKey=G3***w==;EndpointSuffix=core.windows.net";
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
System.out.println("Uploading -> " + mimeType + " ; File name -> " + filename);
return GetOutputStream("vaadin",filename);
}
#Override
public void uploadStarted(Upload.StartedEvent startedEvent) {
System.out.println("Upload started!");
}
#Override
public void uploadSucceeded(Upload.SucceededEvent succeededEvent) {
System.out.println("Upload succeeded!");
}
public OutputStream GetOutputStream(String container, String blob){
OutputStream outputStream = null;
try{
CloudStorageAccount storageAccount = CloudStorageAccount.parse(conn);
CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
CloudBlobContainer blobContainer = blobClient.getContainerReference(container);
CloudBlockBlob cloudBlockBlob = blobContainer.getBlockBlobReference(blob);
outputStream = cloudBlockBlob.openOutputStream();
} catch (StorageException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return outputStream;
}
#Override
public void updateProgress(long readBytes, long contentLength) {
System.out.println("Progress: readBytes -> " + readBytes + " ; contentLength -> " + contentLength);
}
}
Class MainUI
This is the UI page. I just add an upload component.
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.UI;
import com.vaadin.ui.Upload;
import com.vaadin.ui.VerticalLayout;
import org.springframework.beans.factory.annotation.Autowired;
#SpringUI
public class MainUI extends UI {
private VerticalLayout layout;
private Upload upload;
private UploadReceiver uploadReceiver;
#Autowired
public MainUI(UploadReceiver uploadReceiver){
this.uploadReceiver = uploadReceiver;
}
#Override
protected void init(VaadinRequest vaadinRequest) {
// Set layout
layout = new VerticalLayout();
layout.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
setContent(layout);
// Add upload
upload = new Upload("Upload a file", uploadReceiver);
upload.addStartedListener(uploadReceiver);
upload.addSucceededListener(uploadReceiver);
upload.addProgressListener(uploadReceiver);
layout.addComponent(upload);
}
}
Result:
After I clicked the upload button and chose a file to upload, I could get the following outputs from console:
And, by checking the storage account with Storage Explorer, I could see that the file was successfully uploaded:
Update:
This is how the upload works:
I do not know how your code passed the compiling. To construct an Upload object, you need to pass a caption string and a receiver which implements Upload.Receiver interface.
public Upload(String caption, Receiver uploadReceiver)
And to implement the Upload.Receiver interface, you have to override the receiveUpload method.
OutputStream receiveUpload(String filename, String mimeType)
The receiveUpload will return an output stream, where vaadin will finally write contents to.
That's all. Give vaadin an output stream, and it will write all the contents to the stream.
The input file is sent from your browser and handled by vaadin. I did not find a way to manually set the input content in vaadin. Sorry.
I need to implement a function that make a screenshot for a web page in a java backend project. I found some methods like using a headless browser is a good way but none of them performances perfectly (like jbrowser and ashot) for a long page or with too many images. I found that firefox has a function can make a screenshot for me. I wonder is there any java API for this function in headless mode? Or is there any other way to get a better screenshot performance? Thanks a lot
Here is my code to get a screenshot
package screenshot;
import com.machinepublishers.jbrowserdriver.JBrowserDriver;
import com.machinepublishers.jbrowserdriver.Settings;
import com.machinepublishers.jbrowserdriver.Timezone;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.OutputType;
import ru.yandex.qatools.ashot.AShot;
import ru.yandex.qatools.ashot.Screenshot;
import ru.yandex.qatools.ashot.shooting.ShootingStrategies;
import javax.imageio.ImageIO;
import java.io.*;
public class JbrowserTest {
public String chekUrl(String str){
if (str.startsWith("http://") || str.startsWith("https://")) {
return str;
}
return str;
}
public static void main(String[] args) throws UnsupportedEncodingException {
// You can optionally pass a Settings object here,
// constructed using Settings.Builder
JBrowserDriver driver = new JBrowserDriver(Settings.builder().
timezone(Timezone.ASIA_SHANGHAI).screen(new Dimension(1920,1080)).build());
String url3 = "http://www.google.com";
// This will block for the page load and any
// associated AJAX requests
driver.get(url3);
driver.manage().window().maximize();
// You can get status code unlike other Selenium drivers.
// It blocks for AJAX requests and page loads after clicks
// and keyboard events.
System.out.println(driver.getStatusCode());
// Returns the page source in its current state, including
// any DOM updates that occurred after page load
String string2 = new String(driver.getPageSource().getBytes("utf-8"),"gb2312");
System.out.println(string2);
Screenshot screenshot2 = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(100))
.takeScreenshot(driver);
try {
ImageIO.write(screenshot2.getImage(), "PNG",
new File("/Users/*******/Desktop/test2.png"));
byte[] screenshot = driver.getScreenshotAs(OutputType.BYTES);
System.out.println("the bytes" + screenshot.length);
String filePath = "/Users/*******/Desktop/test.png";
File file = new File(filePath);
FileOutputStream fw = new FileOutputStream(file);
fw.write(screenshot);
fw.close();
} catch (Exception ex) {
System.out.println("error" + ex);
}
// Close the browser. Allows this thread to terminate.
driver.quit();
}
}
You don't exactly specify your "performance requirement". An easy way to take screenshots by utilizing selenium and chrome drivers:
private void loadWebpage(){
//Init driver
ChromeOptions options = new ChromeOptions();
options.setHeadless(true);
options.addArguments("--window-size=1200x600", "--log-level=3");
WebDriver driver = new ChromeDriver(options);
//Load your website & wait until loaded with webdriver wait
takeScreenShot(driver, new File("outputFile.png"))
}
public static void takeScreenshot(WebDriver driver, File screenshotFile) throws
IOException {
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
Files.copy(scrFile.toPath(), screenshotFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
I'm trying to load a file from resources/ path using
getClassLoader().getResourceAsStream("file.LIB")
but the method always returns null, unless I rename the file into another extension, say ".dll".
I've looked into the official Java documentation, but to no avail.
Why does the method acts strange on that file type?
Note: I'm using JDK 1.8.0_111 x86 (due to constraints on that lib file, which only works well with a 32-bit JVM)
It does works for me, you need to be sure what exactly you are doing with lib file.
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class FileHelper {
public String getFilePathToSave() {
Properties prop = new Properties();
String filePath = "";
try {
InputStream inputStream =
getClass().getClassLoader().getResourceAsStream("abc.lib");
prop.load(inputStream);
filePath = prop.getProperty("json.filepath");
} catch (IOException e) {
e.printStackTrace();
}
return filePath;
}
public static void main(String args[]) {
FileHelper fh = new FileHelper();
System.out.println(fh.getFilePathToSave());
}
}
This code attempts to resize images in a directory called "imgs". Unfortunately for some reason when I uncomment the listFiles(..) loop ImageIO.read(sourceImageFile) will return null. Yet processing the same file straightaway outside the loop (res("imgs/foto_3.jpg")) works. So apparently, this loop is preventing the files from being read. Solutions?
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import static org.imgscalr.Scalr.*;
public class App {
public static void main(String[] args) throws IOException {
// for (File sourceImageFile : new File("imgs").listFiles()) {
// res("imgs/"+sourceImageFile.getName());
// }
res("imgs/foto_3.jpg");
}
public static void res(String arg) throws IOException {
File sourceImageFile = new File(arg);
BufferedImage img = ImageIO.read(sourceImageFile);
BufferedImage thumbnail = resize(img, 500);
thumbnail.createGraphics().drawImage(thumbnail, 0, 0, null);
ImageIO.write(thumbnail, "jpg", new File("resized/" + sourceImageFile.getName()));
}
}
To reproduce the problem you can download the Maven project.
Can you change res to accept a File object rather than a String? Then you could write the following, which is a lot nicer:
for (File sourceImageFile : new File("imgs").listFiles()) {
res(sourceImageFile);
}
As to your original question, try adding some tracing statements or using a debugger to find what exactly gets passed to res.
I am not sure why the file listing iteration would mess with the thumbnail generation, but you mentioned privately to me that you were using imgscalr and were curious what the correct code to batch-process a directory would look like, so I wrote up this example code for you.
The code below will process any directory (imgs is hard-coded to stay consistent with your example code) and write it out to any other directory (resized is used to stay consistent -- feel free to change either directory)
import static org.imgscalr.Scalr.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ScaleDirExample {
public static void main(String[] args) throws IOException {
File[] images = new File("imgs").listFiles();
for (File f : images) {
System.out.println("Processing: " + f.getName() + "...");
if (f.isDirectory()) {
System.out.println("\tSkipping, file is a directory...");
continue;
} else
process(f);
}
}
private static void process(File file) throws IOException {
// Load image.
BufferedImage image = ImageIO.read(file);
// Resize image.
image = resize(image, 500);
// Save the resized image as the thumbnail.
saveThumbnail(file, image);
}
private static void saveThumbnail(File originalFile, BufferedImage thumbnail)
throws IOException {
String filename = originalFile.getName();
// Determine file extension.
String fileExt = filename.substring(filename.lastIndexOf('.') + 1);
// Save the thumbnail to the resized dir.
ImageIO.write(thumbnail, fileExt, new File("resized/" + filename));
}
}
The call to resize(image, 500) can be modified to match any of the Scalr.resize methods - you can pass filters or improve quality if you want.
Example output from my test setup looks like:
Processing: flower-dog-gimp.jpg...
Processing: flower-dog.jpg...
Processing: logoOXdaComida.png...
Processing: mr-t-thumbnail.jpg...
Processing: mr-t.jpg...
Processing: problem-trans-peter-griffin.png...
Hope that helps!
OK, I figured it out. now it's working.
You (or whoever created the downloadable project u pasted here) are using Mac OS, and it automatically creates a .DS_Store file.
When you try to pass it to the res method, it doesn't know how to handle a non-image file and acts as null.
public static void main(String[] args) throws IOException {
for (File sourceImageFile : new File("imgs").listFiles()) {
if (sourceImageFile.getName().endsWith(".jpg"))
res(sourceImageFile.getAbsolutePath());
}
}
This is the modified void main method. it works, u can refine the if statement for more in depth filtering of wrong files.
Also I changed the argument given to the res method. it looks better now, as getAbsoulutePath returns the name and the path.
Let me know how it worked
One obvious way to debug this to output the specific sourceImageFile that ImageIO.read(..) is returning null on. I suspect its because listFiles will give you a list of all files and directories that are in the image directory. listFiles javadoc. You can prevent that by using a FileFilter that makes sure that listFiles only returns files and additionally files of the right type.
An example of a file filter that only returns file is below:
import java.io.FileFilter
class RegularFilesOnlyFileFilter implements FileFilter {
public boolean accept(File pathName) {
return pathName.isFile();
}
}
The way to use this filter is this - new File("imgs").listFiles(new RegularFilesOnlyFilesFilter())
I've changed res method:
public static void res(File arg) throws IOException {
if (arg.contains(".DS_Store")) {
return;
}
A mac-issue (or should filter non-image files, as was suggested)!
I use this test to convert txt to pdf :
package convert.pdf;
//getResourceAsStream(String name) : Returns an input stream for reading the specified resource.
//toByteArray : Get the contents of an InputStream as a byte[].
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import convert.pdf.txt.TextConversion;
public class TestConversion {
private static byte[] readFilesInBytes(String file) throws IOException {
return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
}
private static void writeFilesInBytes(byte[] file, String name) throws IOException {
IOUtils.write(file, new FileOutputStream(name));
}
//just change the extensions and test conversions
public static void main(String args[]) throws IOException {
ConversionToPDF algorithm = new TextConversion();
byte[] file = readFilesInBytes("/convert/pdf/text.txt");
byte[] pdf = algorithm.convertDocument(file);
writeFilesInBytes(pdf, "text.pdf");
}
}
Problem:
Exception in thread "main" java.lang.NullPointerException
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1025)
at org.apache.commons.io.IOUtils.copy(IOUtils.java:999)
at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:218)
at convert.pdf.TestConversion.readFilesInBytes(TestConversion.java:17)
at convert.pdf.TestConversion.main(TestConversion.java:28)
I use the debugger, and the problem seems to be located here :
private static byte[] readFilesInBytes(String file) throws IOException {
return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
}
What is my problem?
Sounds like the resource probably doesn't exist with that name.
Are you aware that Class.getResourceAsStream() finds a resource relative to that class's package, whereas ClassLoader.getResourceAsStream() doesn't? You can use a leading forward slash in Class.getResourceAsStream() to mimic this, so
Foo.class.getResourceAsStream("/bar.png")
is roughly equivalent to
Foo.class.getClassLoader().getResourceAsStream("bar.png")
Is this actually a file (i.e. a specific file on the normal file system) that you're trying to load? If so, using FileInputStream would be a better bet. Use Class.getResourceAsStream() if it's a resource bundled in a jar file or in the classpath in some other way; use FileInputStream if it's an arbitrary file which could be anywhere in the file system.
EDIT: Another thing to be careful of, which has caused me problems before now - if this has worked on your dev box which happens to be Windows, and is now failing on a production server which happens to be Unix, check the case of the filename. The fact that different file systems handle case-sensitivity differently can be a pain...
Are you checking to see if the file exists before you pass it to readFilesInBytes()? Note that Class.getResourceAsStream() returns null if the file cannot be found. You probably want to do:
private static byte[] readFilesInBytes(String file) throws IOException {
File testFile = new File(file);
if (!testFile.exists()) {
throw new FileNotFoundException("File " + file + " does not exist");
}
return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
}
or better yet:
private static byte[] readFilesInBytes(String file) throws IOException {
InputStream stream = TestConversion.class.getResourceAsStream(file);
if (stream == null) {
throw new FileNotFoundException("readFilesInBytes: File " + file
+ " does not exist");
}
return IOUtils.toByteArray(stream);
}
This class reads a TXT file in the classpath and uses TextConversion to convert to PDF, then save the pdf in the file system.
Here TextConversion code :
package convert.pdf.txt;
//Conversion to PDF from text using iText.
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import convert.pdf.ConversionToPDF;
import convert.pdf.ConvertDocumentException;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfWriter;
public class TextConversion implements ConversionToPDF {
public byte[] convertDocument(byte[] documents) throws ConvertDocumentException {
try {
return this.convertInternal(documents);
} catch (DocumentException e) {
throw new ConvertDocumentException(e);
} catch (IOException e) {
throw new ConvertDocumentException(e);
}
}
private byte[] convertInternal(byte[] documents) throws DocumentException, IOException {
Document document = new Document();
ByteArrayOutputStream pdfResultBytes = new ByteArrayOutputStream();
PdfWriter.getInstance(document, pdfResultBytes);
document.open();
BufferedReader reader = new BufferedReader( new InputStreamReader( new ByteArrayInputStream(documents) ) );
String line = "";
while ((line = reader.readLine()) != null) {
if ("".equals(line.trim())) {
line = "\n"; //white line
}
Font fonteDefault = new Font(Font.COURIER, 10);
Paragraph paragraph = new Paragraph(line, fonteDefault);
document.add(paragraph);
}
reader.close();
document.close();
return pdfResultBytes.toByteArray();
}
}
And here the code to ConversionToPDF :
package convert.pdf;
// Interface implemented by the conversion algorithms.
public interface ConversionToPDF {
public byte[] convertDocument(byte[] documentToConvert) throws ConvertDocumentException;
}
I think the problem come from my file system (devbox on windows and server is Unix).
I will try to modify my classpath.
This problem may be caused by calling methods on test.txt, which can be a folder shortcut. In other words, you're calling a method on a file that doesn't exist, resulting in a NullPointerException.