Netflix / zuul

Zuul is a gateway service that provides dynamic routing, monitoring, resiliency, security, and more.
Apache License 2.0
13.35k stars 2.35k forks source link

Zuul2: Unable to load filters from within a jar #455

Open pcabot opened 6 years ago

pcabot commented 6 years ago

Hi, I am packaging my zuul 2 server application as a jar and I included the groovy filter source files in it (in a com/company/apigateway/filters folder, which is the same path specified in the application.properties file).

When trying to run the app using java -jar myapp.jar, I get an error related to loading filters:

2018-05-30 08:22:31,533 INFO  com.netflix.zuul.init.ZuulFiltersModule [main] Using filter locations: 
2018-05-30 08:22:31,538 INFO  com.netflix.zuul.init.ZuulFiltersModule [main]   com/company/apigateway/filters/inbound
2018-05-30 08:22:31,538 INFO  com.netflix.zuul.init.ZuulFiltersModule [main]   com/company/apigateway/filters/outbound
2018-05-30 08:22:31,538 INFO  com.netflix.zuul.init.ZuulFiltersModule [main]   com/company/apigateway/filters/endpoint
2018-05-30 08:22:31,789 ERROR com.netflix.zuul.FilterFileManager [main] Error accessing directory in classloader. path=com/company/apigateway/filters/inbound
java.lang.IllegalArgumentException: URI is not hierarchical
    at java.io.File.<init>(File.java:418)
    at com.netflix.zuul.FilterFileManager.getDirectory(FilterFileManager.java:142)
    at com.netflix.zuul.FilterFileManager.getFiles(FilterFileManager.java:162)
    at com.netflix.zuul.FilterFileManager.manageFiles(FilterFileManager.java:200)
    at com.netflix.zuul.FilterFileManager.init(FilterFileManager.java:95)
    at com.netflix.governator.internal.JSR250LifecycleAction.call(JSR250LifecycleAction.java:83)
    at com.netflix.governator.ManagedInstanceAction.call(ManagedInstanceAction.java:34)
    at com.netflix.governator.LifecycleModule$LifecycleProvisionListener.onProvision(LifecycleModule.java:175)
    at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:126)
    at com.netflix.governator.ProvisionMetricsModule$MetricsProvisionListener.onProvision(ProvisionMetricsModule.java:46)

So, after looking at the code, it looks like that Zuul is creating a new File object for each filter file found in the class path. But, the constructor of File class does not seem to accept file path from within jars.

The zuul2 wiki also mentions that

The source code for each Filter is written to a specified set of directories on the Zuul server that are periodically polled for changes. Updated filters are read from disk, dynamically compiled into the running server, and are invoked by Zuul for each subsequent request.

Bottom line, in order for Zuul2 to work, the fiters must be packaged in a folder outside the jar. Is that correct ? Thanks

Jovons commented 6 years ago

I think that is right. zuul2 encourages using groovy for filters which is a dynamic jvm language. I guess the developer team wants to have it more like riemann, a real time pipe of processors. zuul 2 is designed to be of such must be because of netflix usages.

artgon commented 6 years ago

You can load filters from a JAR if you use packages or class names, rather than file folders.

pcabot commented 6 years ago

Can you explain what you mean by "use packages or class names" ? Do you mean changing the value of the zuul.filters.root property to something else than : zuul.filters.root=src/main/groovy/com/company/apigateway/filters ?

Can you give an example please ? thanks!

artgon commented 6 years ago

You can use the properties: zuul.filters.packages or zuul.filters.classes. For example: https://github.com/Netflix/zuul/blob/2.1/zuul-sample/src/main/resources/application.properties#L27

rnacharya commented 4 years ago

I have the same issue. I've followed the same path structure as shown in the application.properties file in the zuul2 repository