This is my Dockerfile
FROM Base-Image
COPY --from=baseimage:version /
ENTRYPOINT ["/bin/Startup.py"]
RUN yum install --setopt=obsoletes=0 graalvm20-ee-8-jdk-20.3.3 && \
yum -y install cronie && \
yum clean all
RUN mkdir -p /etc/runit/artifacts && \
mkdir -p /etc/runit/artifacts/projectname/target
COPY ./target/projectname-*.jar /etc/runit/artifacts/projectname/target
COPY ./target/classes/com/company/team/internal/cron/JavaCronFile.class
/etc/runit/artifacts/projectname/target/
COPY ./start.sh /etc/runit/artifacts/projectname
COPY docker/scripts/crontab /etc/crontab
RUN chmod 660 /etc/crontab && \
/usr/bin/crontab /etc/crontab && \
setup-supercronic /etc/crontab
docker/scripts/crontab file :
* * * * * java JavaCronFile
# * * * * * java -cp /etc/runit/artifacts/projectname/target/ JavaCronFile
# * * * * * java -version
I have a dockerfile which copies the java project "projectname" , installs cronie and runs the above crontab.
If I run just
* * * * * java -version
I do see java version getting printed at the cadence ( 1 min in this case) . Also if I go to the docker container and cd /etc/runit/artifacts/projectname/target/ I do see the .class file JavaCronFile.class present.
But for
1: * * * * * java JavaCronFile
2: * * * * * java -cp /etc/runit/artifacts/projectname/target/ JavaCronFile
3: * * * * * java com.company.team.internal.cron.JavaCronFile
4: * * * * * java -classpath /etc/runit/artifacts/projectname/target/
com.company.team.internal.cron.JavaCronFile
I get : Error: Could not find or load main class JavaCronFile.
I have already referred to following stackoverflow links :
1: Cron job for a Java Program
2: What does "Could not find or load main class" mean?
CodePudding user response:
--classpath
can be tricky, but the snippet from Oracle documentation at the end of this post explains it quite well.
You seem to copy both your class files and jar to the container, but do not copy the classes appropriately, nor set the classpath to include the jar file.
To specify a classes directory, the classes must live in the directory that correspond to their package. You copy your target/com/company/team/internal/cron/JavaCronFile.class
to target/JavaCronFile.class
; Java won't read the class in that case because it expects the file to be in target/com/company/team/internal/cron/JavaCronFile.class
in the container, too.
To specify your jar you have to specify the jar. You can do that explicitly or using the *
or *.jar
pattern, but note well java needs to expand those patterns not your shell!
Thus you should not need to copy your classes and only need to add the wildcard to your classpath to match your copied projectname
jar (note the quotes to prevent the shell from expanding "*.jar"):
java -cp "/etc/runit/artifacts/projectname/target/*.jar" com.company.team.internal.cron.JavaCronFile
--class-path classpath
,-classpath classpath
, or-cp classpath
A semicolon (;
) [or:
on Linux] separated list of directories, JAR archives, and ZIP archives to search for class files.Specifying classpath overrides any setting of the
CLASSPATH
environment variable. If the class path option isn't used and classpath isn't set, then the user class path consists of the current directory (.
).As a special convenience, a class path element that contains a base name of an asterisk (
*
) is considered equivalent to specifying a list of all the files in the directory with the extension.jar
or.JAR
. A Java program can't tell the difference between the two invocations. For example, if the directorymydir
containsa.jar
andb.JAR
, then the class path elementmydir/*
is expanded toA.jar:b.JAR
, except that the order of JAR files is unspecified. All.jar
files in the specified directory, even hidden ones, are included in the list. A class path entry consisting of an asterisk (*
) expands to a list of all the jar files in the current directory. TheCLASSPATH
environment variable, where defined, is similarly expanded. Any class path wildcard expansion that occurs before the Java VM is started. Java programs never see wildcards that aren't expanded except by querying the environment, such as by callingSystem.getenv("CLASSPATH")
.-- https://docs.oracle.com/en/java/javase/13/docs/specs/man/java.html