My code is very simple:
(def form-test
"<html><body><form action=\"/\" method=\"POST\"><input type=\"text\" name=\"ss\"/><input type=\"submit\" value=\"submit\"/></form></body></html>")
(defroutes app-routes
(GET "/" [] form-test)
(POST "/" req (str "the req: " req))
(route/resources "/")
(route/not-found "Not Found"))
(def app
(handler/site app-routes))
whenever I try my app on my local machine it works fine, I can see the request parameters, but when I deploy the same thing to heroku the request parameters are always empty... what's going on?
OK so I resolved my issue, the problem was the way my program was being executed in Heroku.
My Procfile previously:
web: lein run -m myapp.core
all I did is change it to:
web: java $JVM_OPTS -jar myapp.jar
basically I had to execute my program as a compiled jar.
Related
I followed the instructions on https://quarkus.io/get-started/ and build this demo using the latest quarkus(2.7).
My java environment is:
when I run quarkus dev it turns out fine like this:
But when I access http://localhost:8080/hello I got an 404 like this:
I should have got a string "Hello RESTEasy" as the demo code is like:
Can any one tell me why would this happen?
I was following this guide on deploying to Heroku and this one for sending email.
Everything works fine in development. My variables are set in Heroku:
heroku config
...
MAILGUN_DOMAIN: https://api.mailgun.net/v3/xxxxxx.mailgun.org
MAILGUN_KEY: key-3-xxxxxx
...
And loaded from the config files like so:
config :take_two, Mailer,
domain: System.get_env("MAILGUN_DOMAIN"),
key: System.get_env("MAILGUN_KEY")
However when I try to send email on Heroku when the Mailgun config is set from environment variables I get this error:
** (FunctionClauseError) no function clause matching in IO.chardata_to_string/1
(elixir) lib/io.ex:346: IO.chardata_to_string(nil)
(elixir) lib/path.ex:467: Path.join/2
(elixir) lib/path.ex:449: Path.join/1
lib/client.ex:44: Mailgun.Client.send_without_attachments/2
This happens when the domain is not set for the Mailgun Client. But it is supposed to be set from the environment variable. I made a simple module to test:
defmodule TakeTwo.Mailer do
require Logger
use Mailgun.Client,
Application.get_env(:take_two, Mailer)
def blank_shot do
Logger.info Application.get_env(:take_two, Mailer)[:domain]
Logger.info Application.get_env(:take_two, Mailer)[:key]
send_email from: "steve#xxx.com", to: "speggy#xxx.com", subject: "Hello", text: "This is a blank shot"
end
When I run TakeTwo.Mailer.blank_shot I see the correct domain/key variables logged followed by the error. I am not sure how to debug the Mailgun client remotely.
Finally, if I recreate the above module in the shell (after running heroku run iex -S mix) it works just fine!?
I feel like when the original module is being loaded perhaps the environment variables have yet to be loaded??
The answer was a little buried in a comment so I wanted to make it easier to find. As the other answer mentions, the environment variables aren't available, but the buildpack lets you configure them to be:
I created a elixir_buildpack.config file and added the following:
config_vars_to_export=(DATABASE_URL MAILGUN_DOMAIN MAILGUN_KEY SECRET_KEY_BASE)
The environment variables aren't available at build time. I had the same issue and decided to get rid of the macro carrying the configuration. You can use this patch to move on.
I'm writing a WLST script to deploy an application with WebLogic 11g. The problem is that when I deploy an application (version A), undeploy it, then deploy version B, it deploys version A.
If I try to solve this by deleting the tmp/_WL_user/appname/ folder, it then won't deploy A or B because it looks in the tmp folder for the application (and fails because I cleared it out). I'm using the nostage option, so I don't understand why it's caching anything.
Any help you can offer would be greatly appreciated. Thanks!
Probably the undeploy of Version A was not successful and Version B was never deployed.
Not sure what you have in the WLST script, could you try with the following:
# let's say the appName is testApp
# can move all of these properties to a props file
appName='testApp'
appPath='/scratch/user/testApp.war'
appTarget='AdminServer'
username='weblogic'
password='weblogic1'
adminURL='t3://hostname:adminport'
# start deploy/undeploy code
connect (username, password, adminURL)
for app in cmo.getAppDeployments():
currAppName = app.getName()
if currAppName == appName :
print('Application' + appName + ' already exists, undeploying...')
undeploy(appName)
# sleep is just to make sure that we don't attempt deploy immediately i.e before server is finished with undeploying
# more like a safe side one, may not be required also
java.lang.Thread.sleep(60000)
print('Now deploying ' + appName)
deploy(appName, appPath, appTarget)
disconnect()
I'm playing around with deploying Clojure/Noir apps on Heroku and I've got my app mostly working. However, one final piece I need is to figure out the hostname of my app when deployed on Heroku. Ideally, I want to do this dynamically instead of hard-coding it.
So, if for example, my app's URL is 'http://freez-windy-1800.herokuapp.com', I want to be able to dynamically get this within my clojure code.
I know that I can look at the incoming request to figure this out, but ideally, I'd like to have some sort of 'setting' where I evaluate an expression once and save the value in a variable that I can then use (coming from the Python/Django world, I'm thinking of the settings.py equivalent in Clojure).
For reference, the code I'm deploying is available at https://github.com/rmanocha/cl-short.
You could set an environment variable in Heroku by
heroku config:add BASE_IRI=http://freez-windy-1800.herokuapp.com
and read it back in Clojure
(defn- base-iri []
(or (System/getenv "BASE_IRI") "http://localhost/"))
Heroku already sets the PORT you can use
(defn -main []
(let [port (Integer. (or (System/getenv "PORT") 8080))]
(run-jetty #'app {:port port})))
Works for me in different environments.
You would typically do this with InetAddress from the Java standard library.
(.getCanonicalHostName (java.net.InetAddress/getLocalHost))
This, however, does not do a DNS lookup.
3 ways to get the hostname. Use as you wish.
(ns service.get-host-name
(require [clojure.java.shell :as shell]
[clojure.string :as str])
(:import [java.net InetAddress]))
(defn- hostname []
(try
(-> (shell/sh "hostname") (:out) (str/trim))
(catch Exception _e
(try
(str/trim (slurp "/etc/hostname"))
(catch Exception _e
(try
(.getHostName (InetAddress/getLocalHost))
(catch Exception _e
nil)))))))
Tried to config smtp in application.conf
mail.smtp.host=smtp.sendgrid.net
mail.smtp.user=${SENDGRID_USERNAME}
mail.smtp.pass=${SENDGRID_PASSWORD}
And in the controller
MultiPartEmail email = new MultiPartEmail();
//... setting from,to,subject,content...
Mail.send(email); //using Play's util
But exception occurs, saying bad user credential when authenticating the smtp server.
One thing I notice is that, when push to heroku and start the app, it would warn:
WARNING: Cannot replace SENDGRID_USERNAME in configuration (mail.smtp.user=${SENDGRID_USERNAME})
WARNING: Cannot replace ENV_SENDGRID_PASSWORD in configuration (mail.smtp.pass=${SENDGRID_PASSWORD})
This may due to the precompile flag is on when deploy?? Here is my Procfile:
web: play run --http.port=$PORT --%prod
I've created a simple Play + SendGrid + Heroku example that works for me:
https://github.com/jamesward/playsendgrid
I'm not sure what is different between this example and your code. The only weird thing I noticed above is where it says ENV_SENDGRID_PASSWORD. Perhaps that environment variable name is wrong.