Java AWS Lambda - Jmagick - java

I am trying to use Jmagick in my AWS Lambda Java code. So far I have done following:
Compiled ImageMagick and Jmagick source on Amazon Linux EC2 and generated .so libraries.
Wrote following code for my Java Lambda on my Windows PC (using ImageMagick and Jmagick for windows).
public String handleRequest(Object input, Context context)
{
System.setProperty("jmagick.systemclassloader","false");
try {
ImageInfo newImageiInfo=new ImageInfo();
newImageiInfo.setFileName("/tmp/oldImage.jpg");
newImageiInfo.setSize("512x512");
newImageiInfo.setUnits(ResolutionType.PixelsPerInchResolution);
newImageiInfo.setColorspace(ColorspaceType.RGBColorspace);
newImageiInfo.setBorderColor(PixelPacket.queryColorDatabase("red"));
newImageiInfo.setDepth(8);
MagickImage addTextImage = new MagickImage();
addTextImage.allocateImage(newImageiInfo);
addTextImage.setYResolution(480);
addTextImage.setXResolution(640);
addTextImage.writeImage(newImageiInfo);
DrawInfo aInfo = new DrawInfo(newImageiInfo);
aInfo.setFont("Arial");
aInfo.setTextAntialias(true);
aInfo.setText("JMagick Tutorial");
addTextImage.annotateImage(aInfo);
addTextImage.setFileName("/tmp/newImage.jpg");
addTextImage.writeImage(newImageiInfo);
}catch (MagickException e) {
e.printStackTrace();
}
UploadtoS3("/tmp/newImage.jpg"); // a simple method for Uploading
return "Hello from Lambda!";
}
Packaged the .so libraries into Lambda deployment package (I am using jar as deployment package).
The code works fine on my PC, but on Lambda it is not generating any image file. Logically there should be one generated at /tmp/newImage.jpg. Also I cannot see any Exception/error in the Lambda logs which.
Is there anything I am doing wrong? What can I do further? If anyone especially with experience in ImagaMagick and Lambda could help, I will be thankful.

Related

Is Jmeter Beanshell support invoke function from Kotlin jar file

I have Kotlin class:
class Ping {
fun ping(from: String): String{
return "Hello $from"
}
}
I've built jar file from this class. and included it to Jmeter and invoked it in BeanShell Sampler:
Ping ping = new Ping();
ping.ping("Jmeter");
it appear error Error invoking bsh method: eval Sourced file: inline evaluation of: ``Ping ping = new Ping(); ping.ping("Jmeter");'' : Method Invocation ping.ping
but I tried to change parameter of the method from string to int it work fine.
Any solution for this problem?
Thank you!
I cannot reproduce your issue using:
JMeter 5.4.1
Kotlin 1.5 (I copied the following .jars to JMeter Classpath just in case)
kotlin-reflect.jar
kotlin-reflect-sources.jar
kotlin-stdlib.jar
kotlin-stdlib-jdk7.jar
kotlin-stdlib-jdk7-sources.jar
kotlin-stdlib-jdk8.jar
kotlin-stdlib-jdk8-sources.jar
kotlin-stdlib-sources.jar
kotlin-test.jar
kotlin-test-sources.jar
The following sample code:
Ping ping = new Ping();
log.info(ping.ping("Jmeter"));
So double check your .jar file and JMeter Classpath. It also worth trying to put your code inside try block like
try {
Ping ping = new Ping();
log.info(ping.ping("Jmeter"));
}
catch (Exception ex) {
log.error("Beanshell failure", ex);
}
this way you will get the root cause of the problem in jmeter.log file
Also be aware that starting from JMeter 3.1 it's recommended to use JSR223 Test Elements and Groovy language for scripting so maybe it worth considering migrating to Groovy, see Apache Groovy - Why and How You Should Use It article for more details, it might be the case you won't need any Kotlin code.

Missing resolveStrategy breaks DSL when executed from runnable jar

I'm using the Groovy Spreadsheet Builder within one of my Grails projects to export some data as Excel file.
Everything works great until I create a runnable jar (using gradle assemble) and use this.
I'm using the builder within a service like this:
class ExcelService {
...
void export(OutputStream outputStream) {
...
PoiSpreadsheetBuilder.create(outputStream).build {
apply ExcelStylesheet
...
}
}
...
}
When I try to export my data from the app started using the generated jar I will get the following MissingMethodException:
groovy.lang.MissingMethodException: No signature of method: my.package.ExcelService.apply() is applicable for argument types: (java.lang.Class)
The (Java) interface of SpreadsheetBuilder looks like this:
public interface SpreadsheetBuilder {
void build(#DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = WorkbookDefinition.class) #ClosureParams(value = FromString.class, options = "builders.dsl.spreadsheet.builder.api.WorkbookDefinition") Configurer<WorkbookDefinition> workbookDefinition);
}
While debugging the execution of the code and the jar I found the difference while stepping through invokeMethod() of ClosureMetaClass.
When closure.getResolveStrategy(); in the working version is called Closure.DELEGATE_FIRST will be returned. Debugging the jar, the result will be 0 so that the MissingMethodException will be thrown later due to the wrong resolve strategy.
For now I have no idea how to solve this problem.
What is/could be the reason for this behavior?
What can I do to solve this issue?
I'm using Grails 3.3.8 with Java OpenJDK 1.8.0_192.
If you don't need to support JDK 7, you could upgrade to Groovy Spreadsheet Builder 2.0.0.RC1 which is only JDK 8 compatible but appears to solve the problem.
#ClosureParams and #DelegatesTo are applicable to parameters of type groovy.lang.Closure. In this case, you have applied it to Configurer<WorkbookDefinition>.

Can Eclipse for Java and Eclipse for WEBMethods be on the same hard drive?

I am new to WEBMethods. I have been working on a Java service for a project. I really need to be able to write some code in regular Java for some quick testing of reading in a simple text expression with some regular expressions. Nothing at all that fancy with the Java part. But eclipse currently is set up for WEBMethods and I need to be in a regular Java mode for Eclipse (If there is such a thing). At home I have the standard eclipse version and have no trouble writting code. But at work I have WEBMethods installed in the Eclipse (Software AG Designer). I think that if I can write the code in regular Java then I can just copy and paste it into the WEBMethods Java services and set up the INPUT and OUTPUT variables and it should work. But currently I cannot find a way to just write Java code like I do from my home computer.
Question: How can I write just a regular Java program (classes, packages, ...etc...) with a machine with WEBMethods installed? Do I have to install another session of Eclipse on my hard drive? (I tried this a while back and there was an issue with having more than one session of Eclipse on the machine).
Java Web Services Code:
package DssAccessBackup.services.flow;
import com.wm.data.*;
import com.wm.util.Values;
import com.wm.app.b2b.server.Service;
import com.wm.app.b2b.server.ServiceException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public final class new_javaService_SVC
{
/**
* The primary method for the Java service
*
* #param pipeline
* The IData pipeline
* #throws ServiceException
*/
public static final void new_javaService(IData pipeline)
throws ServiceException {
// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
String inputFileName = IDataUtil.getString( pipelineCursor, "inputFileName" );
pipelineCursor.destroy();
// pipeline
IDataCursor pipelineCursor_1 = pipeline.getCursor();
IDataUtil.put( pipelineCursor_1, "fileName", "fileName" );
// outDoc
IData outDoc = IDataFactory.create();
IDataUtil.put( pipelineCursor_1, "outDoc", outDoc );
pipelineCursor_1.destroy();
String fileName = new String();
fileName = null;
try {
BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\itpr13266\\Desktop\\TestFile.txt"));
String line = null;
//Will read through the file until EOF
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("Try-Catch Message - " + e.getMessage());
e.printStackTrace();
}
}
// --- <<IS-BEGIN-SHARED-SOURCE-AREA>> ---
// --- <<IS-END-SHARED-SOURCE-AREA>> ---
}
You don't need to install another Eclipse for Java development. WebMethods Designer (v9) comes with Java tooling. Just open the Java perspective and use it.
Besides that you should use the Service Development perspective, when developing WebMethods Java Services, because WM Designer handles Java services in a special way, which could make importing standard Java files difficult.
There is no problem running multiple instances of Eclipse at the same time as long as they point to different workspaces.
Normally you get a dialog to choose the workspace when Eclipse starts up. If not, check this answer on how to enable that dialog: https://stackoverflow.com/a/8616216/1599890
So if you download, unzip and set up Eclipse for Java development and point it to another workspace than Software AG Designer uses you should be good to go.

Running a Java program from Adobe AIR's native process

I've use Adobe native process to run java program from my air app. Here the code and it works fine. But i should write absolute path to java runtime for that:
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java.
If user installed java runtime in diff folder, or have diff version then this code would not work. How i can detect where java were installed or maybe there is another right way to run java applications from air applications? If i run java library from terminal command line then i could just write "java -jar pdfbox-app-1.6.0.jar" etc. and it runs fine.
private function convertPdf2Txt():void{
var arg:Vector.<String> = new Vector.<String>;
arg.push("-jar");
arg.push(File.applicationDirectory.resolvePath("pdfbox-app-1.6.0.jar").nativePath);
arg.push("ExtractText");
arg.push("-force");
arg.push(File.applicationStorageDirectory.resolvePath("Data/1.pdf").nativePath);
arg.push(File.applicationStorageDirectory.resolvePath("Data/1.txt").nativePath);
var fjava:File = new File("/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java");
if (fjava.exists==false){
Alert.show("Can't find Java Runtime in default folder.","Idea Rover",mx.controls.Alert.OK, null,null,imgInfo);
return;
}
var npInfo:NativeProcessStartupInfo;
npInfo = new NativeProcessStartupInfo();
npInfo.executable = fjava;
npInfo.arguments = arg;
var nativeProcess:NativeProcess;
nativeProcess = new NativeProcess();
nativeProcess.addEventListener(NativeProcessExitEvent.EXIT,onNativeProcessExit);
nativeProcess.start(npInfo);
}
Absolute path is:
Mac OS: /usr/bin/java
Win OS: (default)
64bit : C:\Program Files\Java
32bit : C:\Program Files (x86)\Java
rather than popping up an Alert, you could open a file selection dialog, using File.browseForOpen(). then, the File you want is contained in the event passed by the Event.SELECT handler. this flow seems standard for applications i've used that need to access other applications, but aren't sure where to find their executables.
var npInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
// setup npInfo, nativeProcess...
var fjava:File = new File("/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java");
if (!fjava.exists) {
fjava.addEventListener(Event.SELECT, onFileSelected);
fjava.browseForOpen("Where is Java located?");
}
private function onFileSelected (evt:Event) :void {
npInfo.executable = evt.target;
nativeProcess.start(npInfo);
fjava.removeEventListener(Event.SELECT, onFileSelected);
}
of course, you can use the same logic to find the file java needs to launch as well.
You may be able to determine where the Java binaries are by looking at the JAVA_HOME environment variable. I'd like to do the same thing as you're doing, so I'll post more after I do more research.

Is it possible with Java to delete to the Recycle Bin?

Java is the key here. I need to be able to delete files but users expect to be able to "undelete" from the recycle bin. As far as I can tell this isn't possible. Anyone know otherwise?
Ten years later, with Java 9, finally there is a builtin way to move files to the Trash Bin
java.awt.Desktop.moveToTrash(java.io.File):
public boolean moveToTrash​(File file)
Moves the specified file to the trash.
Parameters:
file - the file
Returns:
returns true if successfully moved the file to the trash.
The availability of this feature for the underlying platform can be tested with Desktop.isSupported​(Desktop.Action.MOVE_TO_TRASH).
For various reasons Windows has no concept of a folder that simply corresponds to the Recycle Bin.
The correct way is to use JNI to invoke the Windows SHFileOperation API, setting the FO_DELETE flag in the SHFILEOPSTRUCT structure.
SHFileOperation documention
Java example for copying a file using SHFileOperation (the Recycle Bin link in the same article doesn't work)
Java 9 has new method but in my case I am restricted to Java 8.
I found Java Native Access Platform that has hasTrash() and moveToTrash() method. I tested it on Win 10 and Mac OS (Worked) for me.
static boolean moveToTrash(String filePath) {
File file = new File(filePath);
FileUtils fileUtils = FileUtils.getInstance();
if (fileUtils.hasTrash()) {
try {
fileUtils.moveToTrash(new File[] { file });
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
} else {
System.out.println("No Trash");
return false;
}
}
Maven Repository
https://mvnrepository.com/artifact/net.java.dev.jna/jna-platform/5.1.0
Don't confuse It is Java Native Access Platform not Java Native Access
See the fileutil incubator project (part of the Java Desktop Integration Components project):
This incubator project is created to host those file utility functionalities, most of which are extensions to the java.io.File class in J2SE. There are frequent requests from Java developers for such features like: sending a file to trash bin, checking free disk space, accessing file attributes etc. This project addresses such frequently requested APIs.
Note, this should work not only on Windows, but on other platforms (Linux, Mac OS X) as well.
My 3 cents - use cmd util Recycle.exe with -f to force recycle (no prompt). Works perfectly.
public class Trash {
public void moveToTrash(File ... file) throws IOException {
moveToTrash(false, file);
}
public void promptMoveToTrash(File ... file) throws IOException {
moveToTrash(true, file);
}
private void moveToTrash(boolean withPrompt, File ... file) throws IOException {
String fileList = Stream.of(file).map(File::getAbsolutePath).reduce((f1, f2)->f1+" "+f2).orElse("");
Runtime.getRuntime().exec("Recycle.exe "+(withPrompt ? "" : "-f ")+fileList);
}
}
In JNA platform, the FileUtils doesn't use Win32 API. You should prefer W32FileUtils which supports Undo (restore the file from recycle bin).
Edit: as of the current version of JNA Platform (5.7.0), with FileUtils.getInstance(), this statement has become incorrect, and FileUtils will use the Win32 API.

Categories