Java error trying to run app locally

Hi everyone, this is my first post on the forum.
I don’t have much experience in Anvil, but I need to start managing our organization’s app since the previous devs are on leave. I am trying to run our app locally first, so I can properly test before deploying my code. I’m am running into some java errors while starting the app locally.

What I’m trying to do:
I have cloned my app and its dependencies locally and set up a local clone of the database.
I’m running a Windows machine, here are the JDK specifications

openjdk version "21.0.3" 2024-04-16 LTS
OpenJDK Runtime Environment Corretto-21.0.3.9.1 (build 21.0.3+9-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.3.9.1 (build 21.0.3+9-LTS, mixed mode, sharing)

and the versions of my anvil libraries

anvil-app-server   1.10.1
anvil-uplink       0.4.2

The app has dependencies on anvil_extras and HashRouting

I’m trying to run my app using the following command

anvil-app-server --app <APP_FOLDER> --config-file <APP_FOLDER>\local_config.yaml --auto-migrate

When trying to access the app on http://localhost:3030, I see the following message

Cannot invoke “Object.getClass()” because “target” is null

The console logs show the following

Found Anvil App Server JAR in package directory
Found 7 migration(s) for (base runtime) DB.
Executing Anvil migrations...
Database currently at "2023-03-31-inline-media-storage"
Database is already up to date.
[TRACE anvil.app-server.run] Invalidating; new version 1
[INFO  anvil.core.server] HTTP Server running on port 3030
[INFO  anvil.app-server.run] App URL:  http://localhost:3030
[INFO  anvil.app-server.dispatch] Launching built-in downlink...
[INFO  anvil.app-server.run] SMTP Server running on port 25
Warning: PDF Rendering not supported on Windows. Renderer not initialised
Connecting to ws://localhost:3030/_/downlink
Anvil websocket open
[INFO  anvil.executors.downlink] Downlink client connected with spec {:runtime "python3-full", :session_id "5PeLC7nJT4dmEbNBvyO1"}
Downlink authenticated OK
[TRACE anvil.app-server.run] Invalidating; new version 2
[TRACE anvil.app-server.run] Invalidating; new version 3
[TRACE anvil.app-server.run] Invalidating; new version 4
[ERROR anvil.util] Reporting uncaught exception in GET /
java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "target" is null
        at clojure.lang.Reflector.invokeNoArgInstanceMember(Reflector.java:301)
        at anvil.runtime.read_app_storage$fn__20792$fn__20793.invoke(read_app_storage.clj:138)
        at clojure.lang.MultiFn.invoke(MultiFn.java:229)
        at anvil.runtime.read_app_storage$get_app_yaml_from_resource_directory.invokeStatic(read_app_storage.clj:341)
        at anvil.runtime.read_app_storage$get_app_yaml_from_resource_directory.invoke(read_app_storage.clj:338)
        at anvil.runtime.read_app_storage$get_app_yaml_from_resource_directory.invokeStatic(read_app_storage.clj:339)
        at anvil.runtime.read_app_storage$get_app_yaml_from_resource_directory.invoke(read_app_storage.clj:338)
        at anvil.runtime.read_app_storage$tree_map_to_yaml.invokeStatic(read_app_storage.clj:322)
        at anvil.runtime.read_app_storage$tree_map_to_yaml.invoke(read_app_storage.clj:263)
        at anvil.runtime.read_app_storage$get_app_yaml_from_resource_directory.invokeStatic(read_app_storage.clj:342)
        at anvil.runtime.read_app_storage$get_app_yaml_from_resource_directory.invoke(read_app_storage.clj:338)
        at anvil.app_server.run$load_app.invokeStatic(run.clj:70)
        at anvil.app_server.run$load_app.invoke(run.clj:59)
        at anvil.app_server.run$fn__1611.invokeStatic(run.clj:163)
        at anvil.app_server.run$fn__1611.invoke(run.clj:163)
        at anvil.runtime.app_data$fn__6378$get_app_info_with_can_depend__6379.invoke(app_data.clj:17)
        at anvil.runtime.app_data$get_app_content_with_dependencies.invokeStatic(app_data.clj:138)
        at anvil.runtime.app_data$get_app_content_with_dependencies.invoke(app_data.clj:107)
        at anvil.runtime.app_data$get_app.invokeStatic(app_data.clj:204)
        at anvil.runtime.app_data$get_app.invoke(app_data.clj:201)
        at anvil.runtime.app_data$sanitised_app_and_style_for_client.invokeStatic(app_data.clj:287)
        at anvil.runtime.app_data$sanitised_app_and_style_for_client.invoke(app_data.clj:283)
        at anvil.runtime.server$serve_app$fn__25299.invoke(server.clj:176)
        at anvil.runtime.server$serve_app.invokeStatic(server.clj:173)
        at anvil.runtime.server$serve_app.invoke(server.clj:171)
        at anvil.app_server.run$fn__1677.invokeStatic(run.clj:234)
        at anvil.app_server.run$fn__1677.invoke(run.clj:233)
        at compojure.core$wrap_response$fn__4900.invoke(core.clj:158)
        at compojure.core$wrap_route_middleware$fn__4884.invoke(core.clj:128)
        at compojure.core$wrap_route_info$fn__4889.invoke(core.clj:137)
        at compojure.core$wrap_route_matches$fn__4893.invoke(core.clj:146)
        at compojure.core$routing$fn__4908.invoke(core.clj:185)
        at clojure.core$some.invokeStatic(core.clj:2693)
        at clojure.core$some.invoke(core.clj:2684)
        at compojure.core$routing.invokeStatic(core.clj:185)
        at compojure.core$routing.doInvoke(core.clj:182)
        at clojure.lang.RestFn.applyTo(RestFn.java:139)
        at clojure.core$apply.invokeStatic(core.clj:659)
        at clojure.core$apply.invoke(core.clj:652)
        at compojure.core$routes$fn__4912.invoke(core.clj:192)
        at anvil.runtime.sessions$with_app_session$fn__7050.invoke(sessions.clj:468)
        at anvil.app_server.run$wrap_constant_app$fn__1607.invoke(run.clj:156)
        at compojure.core$routing$fn__4908.invoke(core.clj:185)
        at clojure.core$some.invokeStatic(core.clj:2693)
        at clojure.core$some.invoke(core.clj:2684)
        at compojure.core$routing.invokeStatic(core.clj:185)
        at compojure.core$routing.doInvoke(core.clj:182)
        at clojure.lang.RestFn.applyTo(RestFn.java:139)
        at clojure.core$apply.invokeStatic(core.clj:659)
        at clojure.core$apply.invoke(core.clj:652)
        at compojure.core$routes$fn__4912.invoke(core.clj:192)
        at clojure.lang.Var.invoke(Var.java:381)
        at anvil.app_server.run$wrap_with_origin_scheme_and_port$fn__1689.invoke(run.clj:275)
        at anvil.app_server.run$wrap_provide_source$fn__1666.invoke(run.clj:214)
        at ring.middleware.json$wrap_json_response$fn__1533.invoke(json.clj:139)
        at ring.middleware.flash$wrap_flash$fn__378.invoke(flash.clj:39)
        at ring.middleware.session$wrap_session$fn__479.invoke(session.clj:108)
        at ring.middleware.keyword_params$wrap_keyword_params$fn__517.invoke(keyword_params.clj:53)
        at ring.middleware.nested_params$wrap_nested_params$fn__567.invoke(nested_params.clj:89)
        at ring.middleware.multipart_params$wrap_multipart_params$fn__780.invoke(multipart_params.clj:173)
        at ring.middleware.params$wrap_params$fn__796.invoke(params.clj:67)
        at ring.middleware.cookies$wrap_cookies$fn__25105.invoke(cookies.clj:214)
        at ring.middleware.absolute_redirects$wrap_absolute_redirects$fn__899.invoke(absolute_redirects.clj:47)
        at ring.middleware.resource$wrap_resource_prefer_resources$fn__804.invoke(resource.clj:25)
        at ring.middleware.content_type$wrap_content_type$fn__863.invoke(content_type.clj:34)
        at ring.middleware.default_charset$wrap_default_charset$fn__879.invoke(default_charset.clj:31)
        at ring.middleware.not_modified$wrap_not_modified$fn__852.invoke(not_modified.clj:61)
        at ring.middleware.x_headers$wrap_x_header$fn__349.invoke(x_headers.clj:22)
        at ring.middleware.x_headers$wrap_x_header$fn__349.invoke(x_headers.clj:22)
        at ring.middleware.x_headers$wrap_x_header$fn__349.invoke(x_headers.clj:22)
        at anvil.app_server.run$wrap_retrieve_original_remote_address$fn__1683.invoke(run.clj:271)
        at org.httpkit.server.HttpHandler.run(RingHandler.java:117)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
        at anvil.core.worker_pool$run_one_task_BANG_.invokeStatic(worker_pool.clj:55)
        at anvil.core.worker_pool$run_one_task_BANG_.invoke(worker_pool.clj:38)
        at anvil.core.worker_pool$launch_thread_BANG_$fn__5698.invoke(worker_pool.clj:94)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.base/java.lang.Thread.run(Thread.java:1583)

What I have tried
I am quite lost debugging this error. In particular, I cannot determine which file is failing to run (Is it on my server code? is it on anvil runtime?).

My only idea was to try other jdk versions, so I tried installing Amazon Coretto 11 and 17, with JDK versions 11 and 17 respectively. I got similar error messages (jdk 11 had a less detailed message, but also NullPointerException.).

Any help will be greatly appreciated.

Hi @santiago.migliaccio,

You say,

Does this mean that your app’s code is not normally deployed locally, ie it’s normally deployed in the Anvil cloud? If so, I would strongly recommend testing a clone of your app on anvil.works rather than fighting with the App Server all week!

Looking at that error, something looks squiffly deep in the innards, and the first thing I’d want to check is whether the app directory does in fact contain what it ought to.

To test with a “known good” app folder, I’d suggest creating a fresh app on anvil.works, cloning that locally and launching it with the App Server; alternatively, use create-anvil-app to create an example app and launch that locally.

1 Like

Hi @meredydd, thanks for your suggestions.

The app normally runs on the anvil cloud, but former devs had also a local environment where the app was running too.

The app is running now on the cloud, so there should not be any intrinsic problem with it.

I’ll take your suggestion of trying to start with a clean app and report back. Thanks for your help.

1 Like

If your concern is to test changes before publishing them, you can always make a branch in the anvil ide and push your code to that to test without affecting production.

1 Like

This is the traditional way of developing web apps: develop and test locally, then deploy to the cloud.

And this is one of the reasons why I like Anvil. There is no need to go through the trouble of getting a local functioning environment.

I would try the other suggestion from Meredydd. I would try to test online.

Yes, there are risks. If you are not careful you could mess your production database, but it’s much much easier to test your app online than offline.

The safest way is to clone it, so it’s a brand new copy of the real app with a brand new copy of its tables. A better way is to create a dev branch and test there, making sure that you are not affecting your production database.

But I’m obviously talking without knowing your use case, and your world could be very different from mine.

1 Like

Hi everyone, thank you very much for your help. We’ve managed to fix the issue.

We did a couple more tests: We tried running a new, clean app locally and it worked out. That indicated our app was the problem.
After going around it for a while we realized there was an old custom dependency that had not been maintained in a while, and that wasn’t necessary any more. Removing it eliminated the error and we could run our local environment.

Although we did not find the ultimate reason for the issue (what was the problem within that dependency), running the local environment was our goal, and that is settled.

Thank you everyone for your suggestions. I realize we can do testing directly online in a new branch, and we might adopt that method in the future, but for the moment we need to be able to set the local environment.