How to Make Console Command Availbable to AWS Lambda Written in Java - java

I would like to run a piece of Java code in AWS Lambda that calls a shell command (in my case wkhtmltopdf). I can't seem to figure out how to package the Lambda for this to work:
Cannot run program "wkhtmltopdf": error=2, No such file or directory: java.io.IOException
I've been able to make it work with Node.js. I guess this is due to the "package" being extracted once uploaded whereas with Java the jar stays compressed and thus the executable isn't accessible from java.lang.ProcessBuilder.

I was able to solve this using AWS Lambda Layers. Packagin bin/wkhtmltopdf into a zip file and creating a layer using something along the lines:
aws lambda publish-layer-version --layer-name wkhtmltopdf \
--description "wkhtmltopdf executable" \
--zip-file fileb://$(pwd)/wkhtmltopdf.zip \
--compatible-runtimes java8
After that I was able to select and apply the layer (remember to press save).

Related

how to run kubectl command in java

I can run kubectl get secret/rabbitmq-expressmode -n expressmode in shell successfully.
However when I try to run it in java with either ProcessBuilder or Runtime.getRuntime().exec, the error:
Error from server (BadRequest): the server rejected our request for an unknown reason
is thrown out.
What's the possible reason?
Best approach would be to use official java client library.
Installation is pretty easy, and code examples shows you how to use it.
If the official one does not meet your requirements, there are also community-maintained client libraries:
Java (OSGi)
Java (Fabric8, OSGi)
Java
I had same issue but resolved by programmatically creating bash file containing kubectl... command I was trying to execute directly.
For example, create bash file and put your kubectl command there (i.e.: some-file.sh). Then try then executing it in bash process running within your java code (bash some-file.sh).

How to install chrome inside AWS Lambda

How do I install Chrome in AWS Lambda? I know I might need a specific file from an EC2 instance but I can't figure out how to retrieve it.
not duplicate as as a micro instance ec2 won't be the same enviroment as a lambda
You could create a Lambda Layer with a compiled Google Chrome. There are docker containers emulating Lambda execution environment, e.g. "lambci/lambda:java8". Could be tricky, since you need to build the browser from source code yourself, while there may be many dependencies missing.
Have you tried looking at other people's solutions? For example, this repo seems to have an already compiled Lambda Layer with Google Chrome Google Chrome for AWS Lambda as a layer
You should drop the requirement for Java in this case. It's not your friend.
Switch to Node.js, if only for this Lambda, and use alixaxel/chrome-aws-lambda and Puppeteer.
As AWS Lambda recently announced (2020) the Container Image Support, you can bring your own runtime for your Java code.
A sample Docker Image might look like the following:
FROM public.ecr.aws/lambda/java:11
RUN yum install -y wget unzip libX11
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm && \
yum install -y google-chrome-stable_current_x86_64.rpm
RUN CHROME_DRIVER_VERSION=`curl -sS https://chromedriver.storage.googleapis.com/LATEST_RELEASE` && \
wget -O /tmp/chromedriver.zip https://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip && \
unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/
COPY target/dependency ${LAMBDA_TASK_ROOT}/lib/
COPY target/classes ${LAMBDA_TASK_ROOT}
CMD ["de.rieckpil.test.InvokeWebDriver::handleRequest"]
Once you push this Docker Image to your ECR, you can create a Lambda function that uses your image.
However, I'm still unable to launch Chrome 89 (already tried a gazillion of ChromeOptions arguments combinations) ...
/usr/bin/google-chrome: line 45: /dev/fd/62: No such file or directory
/usr/bin/google-chrome: line 46: /dev/fd/62: No such file or directory
Maybe someone in the future has more success with this and can use this as a template :D

Translating a Jar-opening Batch file into its MacOS Equivalent

Hello again Stack Overflow!
I am currently working on a Java program that is essentially a digitized character sheet for a Dungeons and Dragons style adventure. I'm currently learning how to use IntelliJ IDEA, and while I haven't been able to figure out how to create a standalone executable .jar file, I have been able to find a workaround in the form of a .bat file that I have nicknamed rubberglove.bat (because if you can't open a jar, you use a...).
However, as in my previous post, I've run into a problem, as one of my new players uses a Mac, and since I don't know if it's possible to run rubberglove.bat in a non-Windows environment, I'll probably have to translate it into something MacOS can understand. However, I've never owned a Mac, so I'm not sure what the file extension even is, let alone what to put inside.
The contents of rubberglove.bat are shown below:
java -jar [program_name].jar
What would the Mac equivalent of this file and the commands inside? Thanks in advance for all your help!
Create a file called rubberglove (or rubberglove.sh, the file suffix is optional). And then set the execute bit. Something like
$ cat << EOF > rubberglove
#!/usr/bin/env bash
java -jar [program_name].jar
EOF
$ chmod +x rubberglove
$ ./rubberglove
Error: Unable to access jarfile [program_name].jar
Adjust "[program_name]" as needed.

Jenkins how to print output of command to file even if command fails?

From what i've read, Jenkins logging seems to be done in JVM, where it uses Java's log util class. This is a problem because one of the commands that is run logs nearly 90MB worth of memory. I could technically increase the JVM size, but i couldn't get that to work, AND i would prefer writing this long log to file instead.
let's say i have a command like xcodebuild and this generates 90MB worth of logging. i've instead done this on my jenkins build script:
xcodebuild abc > my_output.txt
However, it seems that my_output.txt does not actually exist if the build failed. This is contrary to how regular bash seems to work. Hmm...
Is there any clever workaround, so that even if the command fails (and logs SOME stuff) that the file is created anyways?
i just want to be able to mail the last 20 lines of the log file to myself upon if the jenkins task failed. But because the file isn't created, the log is gone forever
I would recommend using xctool (wrapper for xcodebuild) that provides the option of specifying a reporter.
# Test the application on iPhone Simulator
xctool -workspace MyProject.xcworkspace \
-scheme "MyProject" \
-reporter plain:tmpoutputs/log.txt \
-reporter junit:tmpoutputs/junit.xml \
clean test \
-test-sdk iphonesimulator8.3 \
-freshInstall
This will output a log file to "tmp outputs/log.txt" and optionally a junit log file for test output if you were to run tests.
Put code similar to this in a shell execution step of Jenkins and you're good to go.

Runtime exec output path

I am trying to run a perl command with Java runtime exec in linux/ubuntu/gnome. The command generates an pdf file, but it saves it in my home folder. Is there any way that the exec method can set an output path for the commands executed? Thanks in advance.
The exec method just runs the command on the operating system, so you'll want to change the command you're running with exec more than anything in "Java" per se.
There are a few possibilities:
Change the working directory of your java program. The .pdf is being saved in your working directory because this is where the program is being run.
Unfortunately it's not simple to change this value after the program has been launched. It is, however, trivial to change before the program starts; just change the working directory before starting the program.
Move the file to it's desired location after it's been created in your home directory.
Change the command so that it includes the target location. Your perl script may have an option that will enable you to save it's output to a certain location (usually -o or --output). Using this your program would change from:
Runtime.exec("perl someprogram");
to something like:
Runtime.exec("perl someprogram -o /path/to/some.file")
You might be able to use "output redirection", if there is no option to do this.
Try something like what's below as your argument:
Runtime.exec("perl someprogram > /path/to/some.file")
Unfortunately, without knowing more details of your situation I can't provide more concrete advice.
While each approach has benefits and drawbacks, it's probably best to just implement the one that you understand best; if you can't get one to work, try another.
A good, free online resource for learning is Introduction to Linux: A Hands On Guide.
Section 2.2 has details on cd which you can use for 1..
Section 3.3, section 3 teaches about the mv command, which will be useful in 2..
Section 5.1 is about I/O redirection. Knowing about "output redirection" and the > operator, are important for 4..
For 3., you'll have to consult the documentation of the perl program you're using.
You could modify the Perl script to accept an absolute path for the output.
You can trying setting the working directory using exec(java.lang.String[], java.lang.String[], java.io.File) where File is the directory the command is executed from.
If all else fails, you'll can always copy the generated file from the Home directory to your final location.

Categories

Resources