Permissions error running Java Timezone Updater JAR in Dockerfile - java

I have a fairly standard Java image with some dependencies added in that I'm writing this Dockerfile on top of. Here's where I'm having a problem in my Dockerfile:
RUN which java
RUN ["/usr/bin/java", "-jar", "tzupdater.jar", "-v", "-l"]
I thought that every Dockerfile command was run as root? But when I try to build from this Dockerfile, I'm running into this permissions issue which also happened in my local environment when I forgot to run this JAR as sudo:
$ docker build -t container-w-tz-update .
Uploading context 1.122 GB
Uploading context
Step 0 : FROM company/java-img-with-dependencies:1.0
---> 0101010101
...
Step 3 : RUN which java
---> Running in 0101010101
/usr/bin/java
---> 0101010101
Step 4 : RUN ["/usr/bin/java", "-jar", "tzupdater.jar", "-v", "-l"]
---> Running in 0101010101
java.vendor: Sun Microsystems Inc.
java.version: 1.6.0_45
tzupdater version 2.1.1-b01
Downloaded file to /tmp/tz.tmp/tzdata.tar.gz
Downloaded file to /tmp/tz.tmp/sha512hash
failed.
Cant rename {0} to {1}.
com.sun.tools.tzupdater.TzRuntimeException: com.sun.tools.tzupdater.TzRuntimeException: Cant rename {0} to {1}.
Caused by: com.sun.tools.tzupdater.TzRuntimeException: Cant rename {0} to {1}.
at com.sun.tools.tzupdater.TimezoneUpdater.update(TimezoneUpdater.java:301)
at com.sun.tools.tzupdater.TimezoneUpdater.run(TimezoneUpdater.java:249)
at com.sun.tools.tzupdater.TimezoneUpdater.main(TimezoneUpdater.java:643)
2017/04/05 22:20:23 The command [/usr/bin/java -jar tzupdater.jar -v -l] returned a non-zero code: 1
I was able to run this utility as sudo on my local with the exact same version of Java with no issues. When I tried to run it locally without sudo, I received the same error. Thoughts?

(This is more like a comment but the message length is beyond the comment limit, so I leave it here as an answer so that other people can maybe give more useful info based on what I've done.)
Seems it's really an unresolved issue, I reproduced your problem by image enoniccloud/java6 running with root user, I also tried docker run -it --privileged ... to run it manually but it does not help. I also tried jdk8 with base image alpine:3.3 but also failed with:
Downloaded file to /tmp/tz.tmp/sha512hash
Renaming /opt/jdk1.8.0_91/jre/lib/tzdb.dat to /opt/jdk1.8.0_91/jre/lib/tzdb.dat.tzdata2016a failed.
Cant rename {0} to {1}.
Validating for : tzdata2017b
Validation complete
JRE updated to version : tzdata2017b
I searched and the only info I found is as follows:
An open issue: https://github.com/docker/hub-feedback/issues/896
Related but not the same: https://forums.docker.com/t/update-docker-container-jre-to-set-timezone-correctly/24426
Before you find the root cause for this issue, I think an alternative way to build your image could be:
Download a JDK tarball for your platform
Untar it, setup JAVA_HOME and PATH, run java -jar tzupdater.jar -v -l on your host
Build your base image based on this updated JDK, ADD to image and setup environment variable like JAVA_HOME and PATH
Hope this could be helpful to you :-)

docker build will complete RUN steps as the last USER set in the Dockerfile.
To reset:
RUN whoami
USER root
RUN ["/usr/bin/java", "-jar", "tzupdater.jar", "-v", "-l"]
USER "whatever whoami reported"

I got a workaround for that. Adding some mv commands (that have no real effect) made it work:
FROM openjdk:7u211-jdk-alpine3.9
ADD tzupdater.jar tzupdater.jar
RUN mv /usr/lib/jvm/java-1.7-openjdk/jre/lib/zi /usr/lib/jvm/java-1.7-openjdk/jre/lib/zi.tzdata2018g && \
mv /usr/lib/jvm/java-1.7-openjdk/jre/lib/zi.tzdata2018g /usr/lib/jvm/java-1.7-openjdk/jre/lib/zi && \
java -jar tzupdater.jar -v -l https://.../tzdata-latest.tar.gz
I have no idea why it works, I got it by trial and error.
Notice the two mv commands do like mv a b && mv b a, so nothing really changes.
The names of the files (dirs, actually) used in the mv are the ones it outputs when it errors (before the workaround), so change it accordingly.

Related

UnsupportedOperationException: No format processor for org.jboss...MavenResolvedArtifact was found

I'm creating an application to automatically generate resources for a launcher, this requires automatically resolving maven dependencies, but I'm getting an UnsupportedOperationException while running JBoss Shrinkwrap Resolver
I'm running this inside a docker container, to avoid the local repository caching, it works outside of the container on the host, but I'm unsure what is missing inside the container.
My resolver config is a simple example, converting to a MavenResolvedArtifact
MavenResolvedArtifact[] artifacts = Maven.configureResolver()
.withMavenCentralRepo(true)
.withRemoteRepo("internal-nexus", MAVEN_URL, "default")
.resolve("com.company:application:" + PROJECT_VERSION)
.withTransitivity()
.asResolvedArtifact();
My Dockerfile is also relatively simple, using openjdk9, including the bootstrapper program, a shell script and some environment variables.
FROM openjdk:9
COPY bootstrapper-shaded.jar /bootstrapper.jar
COPY docker-run.sh /run.sh
ENV CLONE_URL https://github.com/company/repository.git
ENV NEXUS_BASE https://nexus.company.com/
ENV NEXUS_REPO repository
RUN chmod +x /run.sh
RUN apt-get update && apt-get install -y git software-properties-common maven
ENTRYPOINT ["/run.sh"]
And the run.sh script copies some files (removed for brevity), runs the build, then the bootstrapper
#!/bin/sh
rm -rf /boostrap/*
cd /bootstrap/
git clone $CLONE_URL work
cd work
chmod +x ./gradlew
./gradlew clean build
NEXUS_URL=`printf $NEXUS_BASE; printf "/repository/"; printf $NEXUS_REPO` ./gradlew upload
java -jar /bootstrapper.jar 0
I expect the output to be the same as on the host machine, an array of MavenResolvedArtifacts, however the following exception is thrown on the final line of the code snippet, .asResolvedArtifact()
Exception in thread "main" java.lang.UnsupportedOperationException: No format processor for org.jboss.shrinkwrap.resolver.api.maven.MavenResolvedArtifact was found. Supported processors are: class org.jboss.shrinkwrap.resolver.impl.maven.archive.ArchiveFormatProcessor
at org.jboss.shrinkwrap.resolver.spi.format.FormatProcessors.find(FormatProcessors.java:53)
at org.jboss.shrinkwrap.resolver.impl.maven.MavenFormatStageImpl.as(MavenFormatStageImpl.java:84)
at org.jboss.shrinkwrap.resolver.impl.maven.MavenFormatStageImpl.asResolvedArtifact(MavenFormatStageImpl.java:71)
at org.jboss.shrinkwrap.resolver.impl.maven.MavenFormatStageImpl.asResolvedArtifact(MavenFormatStageImpl.java:40)
at com.company.ResolveTask.run(ResolveTask.java:39)
at com.company.Bootstrapper.main(Bootstrapper.java:102)
Apologies for any typos in the stacktrace, VM wouldn't let me copy-paste out of it so I had to type it out myself.
Update: Haven't found anything else on google yet, have tried clean builds to no avail.
You need to change the type of artifacts to
org.jboss.shrinkwrap.resolver.impl.maven.archive.ArchiveFormatProcessor
or at least cast it to that when you declare.

How to make curl available in Docker image based java:8-jdk-alpine and keep the image clean?

We are having java code that runs curl command to fetch the some result.
We have built a jar file and the jar file executes fine
Now, when we try to dokerize the java program (using jar) and run the application in docker we get this error:
errorjava.io.IOException: Cannot run program "curl": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at com.ps.api.common.CoreAPI_Spec.executeCoreAPI(CoreAPI_Spec.java:295)
at com.ps.api.common.CoreAPI_Spec.getAccessTokens(CoreAPI_Spec.java:319)
Dockerfile used :
FROM ubuntu:16.04
MAINTAINER niro;
# Install prerequisites
RUN apt-get update && apt-get install -y \
curl
FROM java:8-jdk-alpine
# Set the working directory to /app
WORKDIR /Users/******/Desktop/CoreAPI_Jar
# Copy the current directory contents into the container at /app
ADD *******_Automation-0.0.1-SNAPSHOT-jar-with-dependencies.jar ******_Automation-0.0.1-SNAPSHOT-jar-with-dependencies.jar
# Run app.py when the container launches
CMD ["java", "-jar", "******-0.0.1-SNAPSHOT-jar-with-dependencies.jar"]
The Java base image you are using is Alpine Linux one and curl package also needs to be downloaded from there. Here is Dockerfile I have used for Production deployments.
FROM openjdk:8-jre-alpine
RUN apk add --update \
curl \
&& rm -rf /var/cache/apk/*
Update 05/2019
As of Alpine Linux 3.3 there exists a new --no-cache option for apk. It allows users to install packages with an index that is updated and used on-the-fly and not cached locally:
FROM openjdk:8-jre-alpine
RUN apk --no-cache add curl
This avoids the need to use --update and remove /var/cache/apk/* when done installing packages.
Reference -
https://github.com/gliderlabs/docker-alpine/blob/master/docs/usage.md and Thank you #Daniel for the comment.
Your example dockerfile contains multiple FROM statements. This is valid but as the documentation says each FROM clears the state from previous instructions. And so the fresh installed curl is wiped after the second FROM.
Most languages have readily available HTTP clients these days; you should almost never be calling out to curl from a program in a language more sophisticated than a shell script. java.net.URLConnection has been a part of Java since Java 1.0 and (without knowing why you're trying to shell out for this) it's almost definitely the right tool here.
Assuming you control the executeCoreAPI method from your backtrace, you should change it to use the built-in Java HTTP client, and just delete all of the Dockerfile parts that try to install curl.

Docker Cloud automated builds - no such file or directory

Running a build of Maven based project but it fails.
The reason is no such file or directory when it tries to find the jar.
Dockerfile:
FROM frolvlad/alpine-oraclejdk8:slim
FROM maven:3.5.2-jdk-8-slim
VOLUME /tmp
CMD ['mvn package']
ADD target/app-0.1.0-SNAPSHOT.jar app.jar <-- fails there
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
The log output:
...
Removing intermediate container 60da937dde8a
Step 4/8 : CMD ['mvn package']
---> Running in 8ba364ba9d98
---> 4a722569d1a7
Removing intermediate container 8ba364ba9d98
Step 5/8 : ADD target/app-0.1.0-SNAPSHOT.jar app.jar
ADD failed: stat /var/lib/docker/tmp/docker-builder1534563/target/app-0.1.0-SNAPSHOT.jar: no such file or directory
ERROR: Build failed: ADD failed: stat /var/lib/docker/tmp/docker-builder1534563/target/app-0.1.0-SNAPSHOT.jar: no such file or directory
ERROR: Build failed with exit code 2
Have played with the different settings but it still doesn't work despite the app name is matches to the built jar one.
How to fix the issue?
This question IMO has nothing to do with Spring Boot, and it's Docker related.
In general please share more information about how exactly you run docker build command, from which directory and where does your Dockerfile reside exactly. Without this information we can only speculate and provide generic answers:
To provide some points for consideration: Docker knows nothing about Maven structure of your project so you can just maintain the following layout:
<some_dir>
|____ Dockerfile
|____ app-0.1.0-SNAPSHOT.jar
Then you can run the docker build command from this directory and this should work. Then you can experiment with target directory and once you'll understand when it works and when it doesn't proceed with your current folders layout, the chances that with this practice you'll find out the answer very quickly.

Docker build hangs during downloads

Mac 10.10.5 here, using docker-machine to create a VirtualBox host VM for my local Docker. I have a project that builds an executable JVM located at build/libs/myapp-SNAPSHOT.jar. My Dockerfile, which is located in the root of the project, looks like:
FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD build/libs/myapp-SNAPSHOT.jar myapp.jar
RUN sh -c 'touch /myapp.jar'
ENTRYPOINT ["java","-jar","/myapp.jar"]
Please note, I don't wish to push my images to any registry, just keep/run them locally (for now). When I run:
docker build -t myorg/myapp .
I get the following console output:
myuser#mymachine:~/sandbox/myapp$docker build -t myorg/myapp .
Sending build context to Docker daemon 42.69 MB
Step 1 : FROM frolvlad/alpine-oraclejdk8:slim
slim: Pulling from frolvlad/alpine-oraclejdk8
d0ca440e8637: Downloading [=================================================> ] 2.295 MB/2.32 MB
0f86278f6be1: Downloading [=================================================> ] 3.149 MB/3.172 MB
c704a6161dca: Download complete
And then the command-line just hangs after printing that "Download complete" message. I've waited for as long as 30 minutes (!!!) and nothing happens.
Any ideas where I'm going awry?
The VM is probably hanging. Try the following: https://github.com/docker/machine/issues/1819#issuecomment-138981139
docker-machine rm -f default
rm -fv ~/.docker/machine
docker-machine -D create -d virtualbox default
There are more issues about this on OSX.
I think the best practice is to setup a Linux native build box if you are doing any serious development. That way you can run docker without any VM overhead(which is ironically one of the major pain points docker is trying to solve)
There's also a Docker Beta program which runs on libcontainer natively on OSX and Windows.

osmdroid-packager Could not find or load main class

This is mostly a java question, and likely something I'm overlooking.
I've been trying to use osmdroid-packager (http://code.google.com/p/osmdroid/wiki/HowToUsePackager) to package map tiles for my android app, on Ubuntu Linux. I've been following the instructions on the site above, and have run into some issues.
I have in my current directory, osmdroid-android-3.0.8.jar, osmdroid-packager-3.0.8.jar, and slf4j-android-1.6.1-RCq.jar. I've setting the classpath, and attempting to run using the commands below gives me the error
'Could not find or load main class
org.osmdroid.mtp.OSMMapTilePackager'
I've also tried different variations of setting the classpath (setting classpath, CLASSPATH, to the jars, to the current directory, with -classpath) with the same result. The best I can come up with is that the class is not in the jar.
The commands I tried from the website above were:
set classpath='osmdroid-android-3.0.8.jar;osmdroid-packager-3.0.8.jar;slf4j-android-1.6.1-RC1.jar;sqlitejdbc-v056.jar'
java org.osmdroid.mtp.OSMMapTilePackager -u http://tile.openstreetmap.org/%d/%d/%d.png -t Mapnik -d haarlem.zip -zmax 18 -n 52.4244 -s 52.3388 -e 4.6746 -w 4.594
java -cp . org.osmdroid.mtp.OSMMapTilePackager
also gives the same error.
I haven't downloaded a copy of sqlitejdbc yet, but I'm pretty sure that's not the issue.
Use a 3.0.3 version to osmdroid-packager , osmdroid-packager for example
Use the same versions od libriries to this prompt command
set classpath=osmdroid-android-3.0.3.jar;osmdroid-packager-3.0.3.jar;slf4j-android-1.5.8.jar;sqlitejdbc-v056.jar
java org.andnav2.osm.mtp.OSMMapTilePackager -u http://tile.openstreetmap.org/%d/%d/%d.png -t Mapnik -d haarlem.zip -zmax 18 -n 52.4244 -s 52.3388 -e 4.6746 -w 4.5949

Categories