I have integrated Image magick with a Java WebApp and have deployed it on Azure App Service. On azure , I am getting 0kb as output image for a image while the same image gets converted fine on my local machine.
I am using im4java for integration with Image Magick.
Below is the code:
public void compressImage(String imageSource, String destinationPath) throws IOException, InterruptedException,
IM4JavaException {
ConvertCmd cmd = getCommand();
// create the operation, add images and operators/options
IMOperation op = new IMOperation();
op.strip();
op.interlace();
op.addRawArgs(compressionRawArguments);
op.gaussianBlur(compressionGaussianBlur);
op.quality(compressedImageQuality);
op.addImage(imageSource); // source file
op.addImage(destinationPath); // destination file
// execute the operation
cmd.run(op);
}
Both imageSource and destination are temp files created using java. I have checked that imageSource file has correct size but after running this code, the destination file is always 0 Kb.
Please advise what could I be doing wrong?
Answering my own question so that It might be helpful for fellow developers who might face this problem.
Azure App Service normally has Windows Server VMs. You can check the OS of your server in web container logs.
Image Magick for windows does not allow conversion of remote http
image urls while for Unix System, it allows so. My Local machine is
MAC So it was working correctly on my local system.
2 Solutions to this problem that I found:
Either you use a linux VM on Azure
In your application, download the image URL to a temp file and
supply the absolute path of that temp file to image magick for
conversion.
I have tried both and are both working.
Related
I'm using IntelliJ and Spring and Java to locally develop an app on a Mac, and then deploy to a tomcat server on AWS, using Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-1048-aws x86_64).
I'm having trouble specifying the file path so that it works in both environments.
My code is
InputStream fileStream = new FileInputStream("src/main/resources/static/web/data/ReportDates.json");
JsonReader reader = Json.createReader(fileStream);
JsonObject reportDates = reader.readObject();
reader.close();
When I run locally, the file is read in correctly. It is located in:
src/main/resources/static/web/data/ReportDates.json
But when I deploy, that code results in the error message:
java.io.FileNotFoundException: src/main/resources/static/web/data/ReportDates.json (No such file or directory)
The actual location of the file on that machine turns out to be:
/opt/tomcat/webapps/automentor/WEB-INF/classes/static/web/data/ReportDates.json
How can I specify the file path so that it works correctly in both environments?
I have given up on using a single path. #Nicholas Pesa got me thinking -- since I use IDEA, I don't have a fixed WEB-INF folder, so it's easier for me to change the path that should be used than to move the file to a fixed location.
My code now uses:
String filepath = (new File("src/main/resources/static/web/data/ReportDates.json").exists()) ? "src/main/resources/static/web/data/ReportDates.json" : "/opt/tomcat/webapps/automentor/WEB-INF/classes/static/web/data/ReportDates.json";
I have developed a Play framework application on my windows PC and then transferred it onto my Linux box, I'm uploading a video and a photo to the server, this upload process works perfectly on my Windows PC, but doesn't work on the Linux box.
code I'm using in windows:
String root = Play.application().path().toString();
String globalFolderPath = root + "/public/globalUploadFolder/";
File globalFolder = new File(globalFolderPath);
Code I tried in Linux as well as the above code:
String globalFolderPath = "../../public/globalUploadFolder/";
File globalFolder = new File(globalFolderPath);
Is there a something I have to do regarding file paths differently on the Linux box, could it be a permission issue?
I'm lost as to why this is happening.
The problem was solved by using File.separator
I am using java webservice (on tomcat).
I have the following code that handles image upload:
public String uploadPicture( long xId,
int pictureIndex,
String imageData )
{
File imageFile = new File( new String( "D:\\" + xId + "_" + pictureIndex ) );
try
{
FileOutputStream fos = new FileOutputStream( imageFile );
byte[] encodedImage = Base64.decode( imageData );
fos.write( encodedImage );
fos.close();
return imageFile.getPath();
}
catch( FileNotFoundException e )
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch( Base64DecodingException e )
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch( IOException e )
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
I specify the path as D:\ since it is on the local PC.
But I need to update it the the path on the server where it will be deployed - then should change it to ~\picDir? something like that?
The webservice url: http://192.168.0.11:8080/XWebService/services/XWebService
will be updated to domain instead of the 192.168.0.11
What should be the URL to get the image? (E.g. if the picture folder is: ~\picDir)
If target server will run Linux/Unix, then proper path should be something like /usr/share/myapp. '~\' is totally wrong, I guess you meant '~/' which will point to home folder of current user. This should be avoided since you might run web server as different users with different home directories. Usually, on each environment (developer machine, demo, live server) you should have such place for storing configuration and data needed by an application.
File System location of your pictures has nothing to do with the URL under which photos will be located. It depends on Web Server (Tomcat, Jetty, JBoss, etc.) which will run your application and your application itself. For instance, you can configure your Tomcat server to map domain www.myapp.com to /var/lib/tomcat6/webapps/myapp/ directory. Servlet which will publish images might take them from configuration dir mentioned in 1. = /usr/share/myapp/picDir. If the servlet can be accessed via /pictures?picId=1 then you will find them under www.myapp.com/pictures?picId=1. However, if you just want to put static images inside your *.war file to be accessed by the browser, put them in root directory of your *.war file.
To summarize:
Choose (and tell us) your application server
Use some configuration directory for all environments and configure your server to be able to see it
Configure your server for desired domain
You should read more about context of *.war files and how the file itself is being organised.
Understanding URLs and context on example of Tomcat
Assuming that:
On your local machine desired servlet is located under: http://localhost:8080/myapp/utils/myservlet.html
Your app is packed as myapp.war
Remote Tomcat has IP 2.2.2.2 and is running on port 8080
When you deploy your myapp.war to remote Tomcat into webapps directory (/var/lib/tomcat6/webapps) it will get unpacked and you will be able to see your servlet under http://2.2.2.2:8080/myapp/utils/myservlet.html. By configuring your application in Tomcat's server.xml you can add domain name and reduce unnecessary "myapp" part called context, effectively leaving URL in form of http://www.myapp.com/utils/myservlet.html. This is what you want in production environment. This topic is explained in Tomcat's documentation, please refer to it.
Accessing File System resources from web application
If you would like to save or get any file from your server, please keep in mind that client (Web Browser) has no idea about underlying disk structure. The browser uses request-response communication pattern which (in terms of upload/download) can be handled by server like this:
upload - grab some byte content from Request and save it as a file on server file system
download - read some byte content from server file system and stream it as a Response
As you can see in both cases server file system is internal concern of the server itself. You can save it anywhere you want. You can read bytes from whatever location. That is why it's good to have MYAPP_CONF (mentioned in comments) to store and read those files always from some predefined directory.
I became so much upset with this simple code segment:
FileConnection fc = (FileConnection) Connector.open("file:///root1/photos/2.png");
System.out.println(is.available());
byte[] fileBytes = new byte[is.available()];
int sizef = is.read(fileBytes);
System.out.println("filesize:"+sizef);
When I deploy this midlet in my mobile (with proper file location) It works properly i.e it shows proper filesize, but in the pc emulator it is constantly giving filesize of: 0. Obviously no Exception and I have the proper file in that location.
I am using j2mewtk sdk in netbeans 6.9. I tried uninstalling, installing wtk & netbeans.
Another thing is Everytime I run the emulator it creates C:\Users\Mahsruf\j2mewtk\2.5.2\appdb\temp.DefaultColorPhone6 new location like temp.DefaultColorPhone1,2,3,4 etc.
If I use jme SDK 3.0 in netbeans the file size is still 0, but now with a extra line in output window: [WARN] [rms ] javacall_file_open: _wopen failed for: C:\Users\Mahsruf\javame-sdk\3.0\work\0\appdb\_delete_notify.dat
What am I doing wrong?
This is not coding related issue. If multiple instances of the same emulator skin run simultaneously, the toolkit generates unique file paths for each one. For example, on Windows instances of DefaultColorPhone might have a file path name of workdir\appdb\temp.DefaultColorPhone1, workdir\appdb\temp.DefaultColorPhone2, and so forth.
Solution: The file workdir\appdb\DefaultColorPhone\in.use keeps track of the number of storage roots marked as in use. If the emulator crashes, you need to delete the in.use file
i am getting a problem
i have deployed a war file, when i run localy through tomcat it works fine but when i run on another system by giveing my system ip and then project folder e.g
http:\192.168.0.145\DllTest it loads the applet but when i click on a button to load the functionality it is throwing an exception
Exception in thread "AWT-EventQueue-3" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library: http:\192.168.0.145:8080\DllTest\lib\jinvoke.dll
while it is working fine localy but not in another system. Please tell me what is the problem.
Is it a rights issue or something else.
You cannot load a DLL on an external host. It has to be an absolute disk file system -as the exception message already hints. Your best bet is to download it manually, create a temp file and load it instead.
File dllFile = File.createTempFile("jinvoke", ".dll");
InputStream input = new URL(getCodeBase(), "lib/jinvoke.dll").openStream();
OuptutStream output = new FileOutputStream(dllFile);
// Write input to output and close streams the usual Java IO way.
// Then load it using absolute disk file system path.
System.loadLibrary(dllFile.getAbsolutePath());
dllFile.deleteOnExit();