jcasbin / casbin-spring-boot-starter

Spring Boot 2.x & 3.x Starter for Casbin, see example at: https://github.com/jcasbin/casbin-spring-boot-example
https://mvnrepository.com/artifact/org.casbin/casbin-spring-boot-starter
Apache License 2.0
196 stars 70 forks source link

Watcher Jedis java.lang.NoSuchMethodError error #78

Closed tunctolgahan closed 1 year ago

tunctolgahan commented 1 year ago

Hi, I enabled watcher configuration (in my application.yml) using this configuration:

casbin:
  enableWatcher: true
  use-synced-enforcer: true

When I do some operation over Enforcer, I get this error: Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: 'java.lang.Long redis.clients.jedis.Jedis.publish(java.lang.String, java.lang.String)'

I googled the error, some says it could be because of Jedis version is incompatible with the Spring Boot version I use (which is 2.7.5).

First, I used the default Jedis package comes with casbin-spring-boot-starter. After I got the error, I upgraded its version to 4.3.1, unfortunately the error still persists.

Any idea why I get this error? Maybe missing configuration on my project? Any solution?

Thanks in advance.

casbin-bot commented 1 year ago

@tangyang9464 @imp2002

hsluoyz commented 1 year ago

@tunctolgahan hi, can you run this example: https://github.com/jcasbin/casbin-spring-boot-example (which uses this casbin-spring-boot-starter)? Does it work?

Did you use another Jedis version in your own project?

tunctolgahan commented 1 year ago

Hi, thanks for your reply. I am a bit busy this week, check it ASAP and let you know.

For your Jedis version question, yes I use more up-to-date version of it in my own project.

tunctolgahan commented 1 year ago

Hi again,

First, I checked the jedis version I use in my own project, it is 4.3.1. And my own project use maven, not gradle.

Second, the example project ran well. I checked all the endpoints defined in it, all returned HTTP 200.

After everything seems OK, I enabled both enableWatcher and use-synced-enforcer. Also I configured spring redis dependency manually (as described in readme file of this repo).

casbin:
  storeType: file
  enableWatcher: true
  use-synced-enforcer: true

spring:
  redis:
    database: 0
    host: localhost
    port: 6379

Then, I created my own endpoints (in DataController) that adds a new policy to casbin db, and returning all policies:

  @Secured("ROLE_ADMIN")
  @PostMapping("/admins/add-policy")
  public ResponseEntity<Data> addPolicy(Authentication authentication) {
    logger.info("addPolicy called");

    List<String> policy = new ArrayList<>();
    policy.add("p");
    policy.add("ROLE_ADMIN");
    policy.add("/data/admins/add-policy");
    policy.add("*");

    enforcer.addPolicy(policy);

    return ResponseEntity.ok().build();
  }

  @Secured("ROLE_ADMIN")
  @GetMapping("/admins/get-all-policies")
  public ResponseEntity<List<List<String>>> getAllPolicies(Authentication authentication) {
    logger.info("getAllPolicies called");

    List<List<String>> policies = enforcer.getPolicy();

    return ResponseEntity.ok().body(policies);
  }

When I called /add-policy and /get-all-policies endpoints from postman, I got this log output. Please see the highlighted line "Method not implemented". Why I got this message? I think this is not something about watcher or synced-enforcer configure, because when I disabled both of them I got the same message after calling /add-policy.

org.casbin.jcasbin                       : Request: [admin, /data/admins/add-policy, POST] ---> true
org.casbin.jcasbin                       : Hit Policy: [ROLE_ADMIN, /data/admins/*, *]
org.casbin.config.CasbinFilter           : session is authorized: B11F208EC2077C80DABBC800DBAAA4F4 admin POST /data/admins/add-policy
org.casbin.controller.DataController     : addPolicy called
org.casbin.jcasbin                       : ****Method not implemented****

org.casbin.jcasbin                       : Request: [admin, /data/admins/get-all-policies, GET] ---> true
org.casbin.jcasbin                       : Hit Policy: [ROLE_ADMIN, /data/admins/*, *]
org.casbin.config.CasbinFilter           : session is authorized: B11F208EC2077C80DABBC800DBAAA4F4 admin GET /data/admins/get-all-policies
org.casbin.controller.DataController     : getAllPolicies called

Also, /admins/get-all-policies returned the all policies as expected (the last policy is the policy I added via endpoint):

[
    [
        "ROLE_USER",
        "/data/users/*",
        "*"
    ],
    [
        "ROLE_ADMIN",
        "/data/users/*",
        "*"
    ],
    [
        "ROLE_ADMIN",
        "/data/admins/*",
        "*"
    ],
    **[
        "p",
        "ROLE_ADMIN",
        "/data/admins/add-policy",
        "*"
    ]**
]

I think there is something wrong with redis/watcher structure on this example project too. Because on redis server, when I checked the "connected client list", I don't see any.

imp2002 commented 1 year ago

Yes, it's seems jedis-client version is incompatible with the Spring Data Redis, Compatible versions are available here, you can switch to you version to see image

try downgraded or upgraded version, or try use the default client in spring-boot-data-redis.

Does example invalid? Did you manually introduce the dependency?

image

hsluoyz commented 1 year ago

Closed as resolved