I get Error: Unable to access jarfile jar-runner.jar when trying to run my jar.
Dockerfile:
FROM anapsix/alpine-java
MAINTAINER bramhaag
CMD ["java", "-jar", "jar-runner.jar", "some param", "some param"]
The jar file is located in /home/selfbot/ and I'm running this with Portainer.
This is what my Portainer container looks like:
How would I make this work?
With CMD [ ] "exec" format, Docker will try to look at the arguments and give its opinion about their usefulness. "Unable to access jarfile" is a Docker message, and it just means Docker has some (unspecified) issues with a jarfile. I've encountered it when the name of the jarfile contained an ENV variable, for instance. Docker couldn't handle that, apparently.
There's also the CMD "shell" format, CMD java -jar jar-runner.jar "some param" "some param". This is known as the shell format because Docker hands of the arguments to /bin/sh -c. As a result, it's not trying to second-guess what the arguments mean. sh in turn doesn't try to be smart either. And java is entirely capable of using jar-runner.jar.
Mind you, if you've got a typo in jar-runner.jar, or you put it in the wrong location, then Docker's message might be right. The shell workaround is useful when Docker guesses wrong.
It looks like you have the volume mounted, so assuming that you are correct that the jar file is available in the container via that volume, you probably just need to specify the path to it so java can find it.
CMD ["java", "-jar", "/home/selfbot/jar-runner.jar", "some param", "some param"]
You can check whether the file is really available by running a different command to just show you the contents of a given directory. Change the command (in Portainer) to something like
ls -la /home/selfbot
And then you can verify whether the jar file is actually where you think it, whether it is readable, etc. This command will exit right away, but its output will be available in the container log.
Try ENTRYPOINT ["java","-jar","jar-runner.jar"]
CMD ["some param"]
I had a similar issue here on my post: Error: Unable to access jarfile when running docker container
Related
kubectl get pods -n abc
NAME READY STATUS RESTARTS AGE
abc-v2-78b59ccc4f-85xgr 0/1 CrashLoopBackOff 27 129m
Facing below error:
> ➜ ~ kubectl logs -f abc-v2-78b59ccc4f-85xgr -n
Error: Unable to access jarfile abc.jar
I am assuming either jar is not present or required access is missing.
Pls guide me here, how to proceed.
Edit 1: As suggested by #howard-roark, Jar is available inside container, getting the same error message.
Edit 2: Check results now with .jar in java command
Edit 4: Ideally there should be only one instance with running status.
Kubernetes is a Container Orchestrator. It runs your images as Containers. The error you are showing looks like an application error and not a Kubernetes error. The way I would approach this is:
Check if the jar file your application calls is in your image. You can do this locally by running your image and exec'ing in to see if your jar file that your application runs is there.
docker run -it <image> /bin/bash
Or you can do a similar command via Kubernetes to exec into your pod:
kubectl run -i --tty testjavacontainer --image=<image> -- /bin/bash
If it is there, then I would confirm its path and make sure that my java command is correctly referencing that path. If it is not there, then I would adjust my Dockerfile to ensure it is at the path that my java command expects.
In short, I would approach this as a standard java error, with the nuance that it happens to run in a container.
I've been trying to create an installer for a program I wrote in Java, implementing GhostScript, that creates a virtual printer where the file is sent to. My program then reads the files and manages it accordingly. However, I had to manually configure the RedMon Redirect Port (RPT1:) and manually created a new printer, using that port, taking as arguments the .jar file:
Arguments configured on the printer's port:
I was able to create a new printer via NSIS (the program I'm using to create the installer) like so:
Exec 'cscript "C:\Windows\System32\Printing_Admin_Scripts\pt-BR\prnport.vbs" ^ -a -r RPT1:'
ExecWait 'rundll32 printui.dll,PrintUIEntry /if /f "$INSTDIR\ghostpdf.inf"^ /r "RPT1:" /m "Ghostscript PDF" /b "Impressora SPE" /u /Y'
Is there a way to do the same, via commands, for configuring ports? If possible, I'd like to create a separate port for my program (currently I'm using the default RedMon port), but also pass the Java arguments to it on installation, so the end user doesn't have to manually include these arguments. I've looked everywhere, but every guide and article I found had it done manually.
Thanks for any help!
It took me a bit of digging, but I finally found the command required to setup a new printer port using RedMon, and figured I'd share it here so less people have a hard time finding it.
rundll32 "REDMONPATH\redmon32.dll", RedMonConfigurePort Port="PORT:" Command="JAVA" Arguments="-jar ""JAR"" ""C:\Program Files (x86)\gs\gs9.21\bin\gswin32c -I\""C:\Program Files (x86)\gs\gs9.21\lib\"" -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sPAPERSIZE=a4 -r300"""
Where REDMONPATH is the path to your RedMon installation folder, PORT is your port's name, JAVA is your path to the java.exe, and JAR is the path to your .jar file. DO keep the double quotes, it's how we pass quotes via commands. You must run this command on the RedMon installation folder, though. Also, you MUST run as an administrator, otherwise you might get an error and wrongly assume you did something wrong. In my case, using NSIS, this is the full command line:
ExecWait 'rundll32 "$INSTDIR\redmon\redmon32.dll", RedMonConfigurePort Port="SPE:" Command="C:\Program Files (x86)\Java\jre1.8.0_144\bin\java.exe" Arguments="-jar ""C:\Program Files (x86)\Impressora SPE\ImpressoraSPE.jar"" \""C:\Program Files (x86)\gs\gs9.21\bin\gswin32c -l \""C:\Program Files (x86)\gs\gs9.21\lib\"" -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sPAPERSIZE=a4 -r300"""'
After that, you can install your new printer using the new port normally:
ExecWait 'rundll32 printui.dll,PrintUIEntry /if /f "$INSTDIR\ghostpdf.inf" /r "PORT:" /m "Ghostscript PDF" /b "PRINTER_NAME" /u /Y'`
If you're trying to run this from the command prompt and not NSIS, all you gotta do is remove the "ExecWait" bit and the single quotes around the command. Also replace "$INSTDIR\something" by the corresponding full path.
If anyone else needs further help with this subject, seeing that I personally had quite a hard time with it, feel free to ask them here and I'll try my best to help!
EDIT: I apologize for the constant edits, just making sure to leave the instructions that help the most people as I test these in different version of Windows.
I am getting some inconsistent behavior in connection with overriding CMD in a derived Dockerfile.
The base Dockerfile looks something like this:
FROM myVeryBaseImage
ENV WEBAPP_CONTEXT=my-app
WORKDIR /opt/${WEBAPP_CONTEXT}
COPY app/*.jar ./${WEBAPP_CONTEXT}.jar
COPY baseconfig/* ./config/${WEBAPP_CONTEXT}/
CMD java -jar ${WEBAPP_CONTEXT}.jar --Dspring.profiles.active=docker
This base image is provided by another team and it would be difficult to change it. I am now composing a bunch of containers where I want to run the same app multiple times, but with different configurations.
So I figured I'd extend the image copying some more configuration into it and running it with a different spring profile:
FROM baseImage
COPY config/application-*.properties ./config/${WEBAPP_CONTEXT}/
CMD java -jar ${WEBAPP_CONTEXT}.jar -Dspring.profiles.active=${PROFILE}
And in the docker-compose.yml:
myapp-foo:
build: ./myapp-custom
image: myapp-custom
environment:
PROFILE: foo
volumes:
- /opt/my-app/foo:/opt/my-app
myapp-bar:
image: myapp-custom
environment:
PROFILE: bar
volumes:
- /opt/my-app/bar:/opt/my-app
I would have expected to have 2 containers running, using the application-foo.properties and application-bar.properties respectively.
It seems, though, that both use the appplication-docker.properties , i.e. the docker profile defined in the base Dockerfile.
If I change the CMD in the derived Dockerfile completely, it works:
CMD echo "${PROFILE}"
Output is "foo" and "bar", respectively. Any hints what might be going on?
My versions are:
docker-compose version 1.8.1, build 878cff1
Docker version 1.12.3, build 6b644ec
Update:
After #blackibiza's suggestions, I changed the derived Dockerfile to
FROM baseImage
COPY config/application-*.properties ./config/${WEBAPP_CONTEXT}/
ENTRYPOINT /opt/jdk1.8.0_102/bin/java
CMD ["-jar", "${WEBAPP_CONTEXT}.jar", "-Dspring.profiles.active=foo"]
Without the docker-compose stuff, just to see how the derived image would look like. I get error messages from java, trying to run the container. Inspecting the image gives the following:
$ docker inspect --format='{{.Config.Cmd}} {{.Config.Entrypoint}}' testapp
[-jar ${WEBAPP_CONTEXT}.jar -Dspring.profiles.active=french] [/bin/sh -c /opt/jdk1.8.0_102/bin/java]
So it still tries to execute /bin/sh and not java. That doesn't look like what I would have expected from the documentation.
Update2:
Using the JSON-array syntax for CMD triggers another problem:
FROM baseImage
COPY config/application-*.properties ./config/${WEBAPP_CONTEXT}/
CMD ["java", "-jar", "${WEBAPP_CONTEXT}.jar", "-Dspring.profiles.active=foo"]
Will not expand the use of ${WEBAPP_CONTEXT} and therefore result in an error
Error: Unable to access jarfile ${WEBAPP_CONTEXT}.jar
What you are looking for is the override of the entrypoint.
As described in the Docker reference,
If you want to run your without a shell then you must
express the command as a JSON array and give the full path to the
executable. This array form is the preferred format of CMD. Any
additional parameters must be individually expressed as strings in the
array:
FROM ubuntu
CMD ["/usr/bin/wc","--help"]
If you would like your container to run the same executable every
time, then you should consider using ENTRYPOINT in combination with
CMD. See ENTRYPOINT.
While with Composer you can override the CMD arguments like explained here:
db:
command: '-d'
ports:
- 5432:5432
you should define an ENTRYPOINT, which is in your case:
ENTRYPOINT java
CMD ["-jar", "${WEBAPP_CONTEXT}.jar"]
In your specific case, I will argue to expose the shell as entry point and override the CMD with a script, like:
ENTRYPOINT /bin/sh
CMD ["./script.sh"]
and in your compose YML:
command: './script2.sh'
UPDATE (based on changed question):
What it's missing is the definition of the variable. In this case, I suggest to use ARG instead of ENV to build the container with the permanent value passed in:
docker build -t your_image:your_version --build-arg WEBAPP_CONTEXT=your_context .
to get a substitution of the value at build time. The ARG has the advantage of being inherited in your child images
Don't just copy & paste faulty Java commands. The -Dspring.profile.active argument will not be recognized if it comes after the .jar file.
Fix the CMD line to be
CMD java -jar -Dspring.profiles.active=${PROFILE} ${WEBAPP_CONTEXT}.jar
and all is well.
See also "Setting active profile and config location from command line in spring boot"
There's an issue when I run the android Runtime.getRuntime().exec method.
I have a native binary file to be run on android and I start it with the java method Runtime.getRuntime().exec. But running this native binary file requires the addition of an environment variable. So I execute this command:
envSetCmd = {"sh", "-c", "export LD_LIBRARY_PATH="+excBinFilepath+":$LD_LIBRARY_PATH"}.
It doesn't work when I check the environment variable with the command:
sh, -c, echo $LD_LIBRARY_PATH.
I think the reason is that when I set the environment variables I start a shell and when I check it with the command "echo" another shell was started. So the environment variables didn't work in the shell I check it.
I think there are two ways to solve this issue. The one is that running two commands in one shell. So I tried to use the command:
{"sh", "-c", "export LD_LIBRARY_PATH="+excBinFilepath+":$LD_LIBRARY_PATH", "-c", "echo $LD_LIBRARY_PATH"}.
Unfortunately it is illegal. The other is that I add the environment variables to the android user startup files. I tried to echo the $PATH, and I see the /system/bin/ and other path was loaded at the startup of android.
So I think there must be a file just like the ~/.bashrc in linux which could set the users' environment.
Any one could give me some clues about the ways I listed above? By the way, I shouldn't root the phone!
try to execute whatever you need to execute with env:
{"env", "LD_LIBRARY_PATH="+excBinFilepath, "yourCmd"}
In a bash shell script I tried these two versions:
java -jar abc.jar&
and
CMD="java -jar abc.jar&"
$CMD
The first verison works, and the second version complains that abc.jar cannot be found. Why?
Commands do run from current directory in a shell script.
This is why the first command in your test script worked.
The second command may not work because either java isn't in your ${PATH} or abc.jar isn't in your ${CLASSPATH}. You could echo these environment variables or set +x to debug your bash script.
Bash (and others) won't let you do backgrounding (&) within the value of a variable (nor will they let you do redirection that way or pipelines). You should avoid putting commands into variables. See BashFAQ/050 for some additional information.
What is the actual error message you're getting? I bet it's something like "abc.jar& not found" (note the ampersand) because the ampersand is seen as a character in the filename.
Also, the current directory for the script is the directory that it is run from - not the directory in which it resides. You should be explicit about the directory that you want to have your file in.
java -jar /path/to/abc.jar&