Closed fakoe closed 3 years ago
Hi thank you for your interest in OpenFaaS.
Contributions are welcome, feel free to work on and propose a solution.
Alternatively, we offer consulting and a [Premium Subscription]](https://openfaas.com/support) if you want us to look at this as a priority.
Alex
I resolved the issue with the following two solutions:
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:23.0'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
compile 'com.openfaas:model:0.1.1'
compile 'com.openfaas:entrypoint:0.1.0'
compile 'my.custom.dependency:my-custom-jar:'
}
I'm fairly new to gradle, so I had no clue that it works like this.
The second solution would be to change the Dockerfile and copy the external libraries from the builder image into the ship image: (The following is a snippet from the Dockerfile)
...
WORKDIR /home/app
COPY --from=builder /home/app/function/build/distributions/function-1.0.zip ./function-1.0.zip
USER app
RUN unzip ./function-1.0.zip
COPY --from=builder /home/app/libs/* ./function-1.0/lib/
...
Problem with the second solution would be, that external jars have to be in a folder called "libs" under the root directory ./libs Since it makes more sense to include external dependencies into the ./function folder, I'd change the Dockerfile to:
...
WORKDIR /home/app
COPY --from=builder /home/app/function/build/distributions/function-1.0.zip ./function-1.0.zip
USER app
RUN unzip ./function-1.0.zip
COPY --from=builder /home/app/function/lib/* ./function-1.0/lib/
...
(There might be problems with permissions due to USER app, I haven't tested that)
I think the first solution is more than enough, but if, for any reason, somebody can't use "compile" instead of "implementation", the second approach might come in handy (even if it is hard-coded).
Thanks for the reply. Can you re-iterate your first solution? I didn't quite follow it.
/set title: Support issue for Java11 and local libraries
I think I just failed to understand the build.gradle script. I'm new to gradle and thought that I need to declare local libaries in the dependencies like this:
dependencies {
implementation 'my.custom.dependency:my-custom-jar:'
}
When I actually have to do this:
dependencies {
compile 'my.custom.dependency:my-custom-jar:'
}
implementation
lets you execute gradle build
without any errors, but the jars aren't added to the final, compiled function.jar, whereas compile
does add them. And since your dockerfile executes gradle build
in another image than the function.jar is used in, the local libraries are staying in the untagged image.
When using the java11 template and implementing my locally stored external jars, they exist at compile-time, since faas-cli build runs without error. But after deploying the function to the OpenFaaS-Server, there is only the function-1.0 folder with the function-1.0.jar and the following libs in a lib folder:
Where are my declared, external libraries and how can I implement them into the docker container correctly? I followed your tutorials, but it doesn't work (well, it works at compile-time but not at runtime).
Expected Behaviour
Declaring external libraries in the build.gradle script should implement them within the docker container. Invoking my function should execute the Handler correctly.
Current Behaviour
My custom written handler, which depends on these libraries isn't able to run, because there is a NoClassDefFoundError, when I call my classes:
At compile-time the classes are existing, since the faas-cli build command successfully builds the function. But at runtime, the function runs into an error and stops, because there aren't any of my dependencies within the created docker container.
My build.gradle script within the function folder looks like this (according to your template documentation):
I saved my-custom-jar.jar under ../libs, as the folder was already declared within the gradle script. So I did everything, that you said in your template documentation and blog post about java11.
Possible Solution
I have no idea, but I assume either adjusting the Dockerfile to copy the libraries or explaining step-by-step how to correctly implement the dependencies within the build.gradle script (Your documentation and blog entry still has code examples from the java8 template, like
compile project(':model')
instead ofcompile 'com.openfaas:model:0.1.1'
).Steps to Reproduce (for bugs)
Context
I work at a software company and we want to use OpenFaaS for exporting longer running tasks of our software. For that, we customized the Handler.class and we use use locally stored, external dependencies, which we declared in the build.gradle script. But when we have the function running in a docker container on our openshift cluster, our dependencies aren't there and we get a NoClassDefFoundError. Strangely, we still get a Response Code of "200" when we invoke the function. Nothing else happens, though.
Your Environment
Docker version
docker version
(e.g. Docker 17.0.05 ): Docker version is 19.03.8Are you using Docker Swarm or Kubernetes (FaaS-netes)? We ware using OpenFaaS on a on-premise OpenShift-Cluster
Operating System and version (e.g. Linux, Windows, MacOS): CentOS 7