VirusTotalNet icon indicating copy to clipboard operation
VirusTotalNet copied to clipboard

java template with external dependencies

Open mattnelson opened this issue 6 years ago • 11 comments

Unable to use external dependencies with the java8 template. https://github.com/openfaas/templates/tree/master/template/java8#external-dependencies

Expected Behaviour

The build should succeed.

Current Behaviour

The command faas-cli build -f jdbc.yml fails.

> Task :model:compileJava
Download http://my-repo/com/oracle/ojdbc8/12.2.0.1/ojdbc8-12.2.0.1.pom
Download http://my-repo/com/oracle/ojdbc8/12.2.0.1/ojdbc8-12.2.0.1.jar
> Task :function:compileJava
> Task :entrypoint:compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Could not resolve all files for configuration ':entrypoint:compileClasspath'.
> Could not find com.oracle:ojdbc8:12.2.0.1.
  Required by:
      project :entrypoint > project :function

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 10s
3 actionable tasks: 3 executed
The command '/bin/sh -c gradle build' returned a non-zero code: 1

Possible Solution

Steps to Reproduce (for bugs)

  1. faas-cli new --lang java8 jdbc
  2. Add code snippet below to method stub
  3. Add compile 'com.oracle:ojdbc8:12.2.0.1' to build.gradle

Context

Unable to build java fn from template when using dependencies not from jcenter.

Your Environment

  • Docker version docker version (e.g. Docker 17.0.05 ):
Client:
 Version:           18.06.0-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        0ffa825
 Built:             Wed Jul 18 19:05:26 2018
 OS/Arch:           darwin/amd64
 Experimental:      false
Server:
 Engine:
  Version:          18.06.0-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       0ffa825
  Built:            Wed Jul 18 19:13:46 2018
  OS/Arch:          linux/amd64
  Experimental:     true
  • Are you using Docker Swarm or Kubernetes (FaaS-netes)? kube

  • Operating System and version (e.g. Linux, Windows, MacOS): MacOS

  • Link to your project or a code example to reproduce issue:

    public IResponse Handle(IRequest req) {
		Response res = new Response();
		try(java.sql.Connection conn = java.sql.DriverManager.getConnection(req.getBody())) {
		  res.setBody("connected");
		} catch (Exception e) {
  	      res.setBody(e.toString());
		}
	    return res;
    }

mattnelson avatar Aug 09 '18 19:08 mattnelson

Hi there, can you update your gradle build file to add in the source that "is not jcenter"?

alexellis avatar Aug 09 '18 19:08 alexellis

This was the generated file and I added my dep and repo. Model and function build. Entrypoint does not build.

Download https://jcenter.bintray.com/com/google/guava/guava/23.0/guava-23.0.jar Task :model:compileJava Download http://my-repo/com/oracle/ojdbc8/12.2.0.1/ojdbc8-12.2.0.1.pom Download http://my-repo/com/oracle/ojdbc8/12.2.0.1/ojdbc8-12.2.0.1.jar Task :function:compileJava Task :entrypoint:compileJava FAILED

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java Library project to get you started.
 * For more details take a look at the Java Libraries chapter in the Gradle
 * user guide available at https://docs.gradle.org/4.8.1/userguide/java_library_plugin.html
 */

plugins {
    // Apply the java-library plugin to add support for Java Library
    id 'java-library'
}

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'

    // my new dep
    compile 'com.oracle:ojdbc8:12.2.0.1'

    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'

    compile project(':model')
}

// In this section you declare where to find the dependencies of your project
repositories {
    // Use jcenter for resolving your dependencies.
    // You can declare any Maven/Ivy/file repository here.
    jcenter()
    maven { url 'http://my-repo/' }
}

mattnelson avatar Aug 09 '18 19:08 mattnelson

Can you export/expose the dependencies from the function project? They get built in a specific order so I would imagine once it's downloaded it should be available in the cache for other projects. I'm not really sure why the entry point would try to access the ojdbc dependency?

alexellis avatar Aug 09 '18 21:08 alexellis

Derek add label: support

ivanayov avatar Aug 10 '18 07:08 ivanayov

I think I traced this down to a few different issues.

I added mavenCentral and mavenLocal to https://github.com/openfaas/templates/blob/master/template/java8/build.gradle#L9 in order to get the build to pass when triggered directly via gradle clean build

When triggered via faas-cli build jdbc.yml the build is executed in a docker container which can't determine where maven local is due to a volume not being mounted. https://github.com/openfaas/templates/blob/a32677a7552fe69d22bc44347959df00548700a5/template/java8/Dockerfile#L23

Not too familiar with gradle(I use maven). The mavenLocal config is kinda a hack. Maven picks up transitive repositories automatically, I would expect gradle to do the same, without having to extra config for exporting deps.

mattnelson avatar Aug 13 '18 16:08 mattnelson

@mattnelson can you please share the error from faas-cli build?

ivanayov avatar Aug 23 '18 14:08 ivanayov

Glad you got this working. I'd like us to improve the template if possible. Do you have any suggestions?

alexellis avatar Sep 13 '18 07:09 alexellis

can you please share the error from faas-cli build?

It is provided with the original issue report > https://github.com/openfaas/templates/issues/62#issue-349256427

Glad you got this working. I'd like us to improve the template if possible. Do you have any suggestions?

I could only get it working when bypassing faas-cli build. I think this is blocked by https://github.com/moby/moby/issues/14080 since the local m2 repo needs to bound to ~/.m2/repository during docker build

mattnelson avatar Sep 17 '18 18:09 mattnelson

I'm also interested in solving this problem. I get the same error. I'm also not very familiar with gradle, so trying to figure it out.

MattMacGillivray avatar Apr 14 '19 05:04 MattMacGillivray

Seems like a gradle knowledge issue. After reviewing this page - https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph - it seems as though changing:

compile 'com.oracle:ojdbc8:12.2.0.1' to compileOnly 'com.oracle:ojdbc8:12.2.0.1'

Allows the function to be compiled. Not sure if it'll run yet. External jars, available through public repositories like jcenter or mavenCentral, work using the implementation keyword.

This might provide a hint to the real solution.

MattMacGillivray avatar Apr 16 '19 19:04 MattMacGillivray

This may be a repeat of what @mattnelson said above, but if you create a java8 function called my-function, adding a private maven repo, that private repo isn't resolved when faas-cli build -f my-function.yml builds the entrypoint subproject.

If you look into build/my-function you will see that it fails to compile the build/my-function/entrypoint subproject, at these lines in the build.gradle:

    compile project(':model')
    compile project(':function')

If I add my private repo to the build/my-function/entrypoint/build.gradle and perform a gradle build, it completes successfully. If I add my private repo to template/java8/entrypoint/build.gradle, generate a new function and build, it also builds successfully.

So the workaround is for me to create my own private template, with my private repo defined within the entrypoint/build.gradle.

Must be a better way to do that?

MattMacGillivray avatar Apr 17 '19 20:04 MattMacGillivray