R
Railway16mo ago
bonjr

Deployment and logging issues (Maven)

Hello, My program is running fine locally, but when I deploy it with Railway, I start seeing issues. I think the issue is primarily with grabbing the environment or database variable.
private static Connection getConnection() throws SQLException {
// String dbUrl = toJdbcUrl(readFromFile("DATABASE_URL")); // local testing
String dbUrl = toJdbcUrl(System.getenv("DATABASE_URL")); // live

return DriverManager.getConnection(dbUrl);
}

private static String toJdbcUrl(String databaseUrl) {
if (databaseUrl == null || !databaseUrl.startsWith("postgresql://")) {
return null;
}

int protocolEnd = databaseUrl.indexOf("://");
int credentialsEnd = databaseUrl.lastIndexOf("@");

String credentials = databaseUrl.substring(protocolEnd + 3, credentialsEnd);
String[] splitCredentials = credentials.split(":");

String user = splitCredentials[0];
String password = splitCredentials[1];

String afterCredentials = databaseUrl.substring(credentialsEnd + 1);
String host = afterCredentials.substring(0, afterCredentials.indexOf(":"));
String portAndDatabase = afterCredentials.substring(afterCredentials.indexOf(":") + 1);

String jdbcUrl = "jdbc:postgresql://" + host + ":" + portAndDatabase + "?user=" + user + "&password="
+ password;

return jdbcUrl;
}
private static Connection getConnection() throws SQLException {
// String dbUrl = toJdbcUrl(readFromFile("DATABASE_URL")); // local testing
String dbUrl = toJdbcUrl(System.getenv("DATABASE_URL")); // live

return DriverManager.getConnection(dbUrl);
}

private static String toJdbcUrl(String databaseUrl) {
if (databaseUrl == null || !databaseUrl.startsWith("postgresql://")) {
return null;
}

int protocolEnd = databaseUrl.indexOf("://");
int credentialsEnd = databaseUrl.lastIndexOf("@");

String credentials = databaseUrl.substring(protocolEnd + 3, credentialsEnd);
String[] splitCredentials = credentials.split(":");

String user = splitCredentials[0];
String password = splitCredentials[1];

String afterCredentials = databaseUrl.substring(credentialsEnd + 1);
String host = afterCredentials.substring(0, afterCredentials.indexOf(":"));
String portAndDatabase = afterCredentials.substring(afterCredentials.indexOf(":") + 1);

String jdbcUrl = "jdbc:postgresql://" + host + ":" + portAndDatabase + "?user=" + user + "&password="
+ password;

return jdbcUrl;
}
The reason I think it's some database/environment issue is because the logs on Railway says:
Exception in thread "main" javax.security.auth.login.LoginException: The provided token is invalid!

at net.dv8tion.jda.internal.JDAImpl.verifyToken(JDAImpl.java:362)

at net.dv8tion.jda.internal.JDAImpl.login(JDAImpl.java:279)

at net.dv8tion.jda.internal.JDAImpl.login(JDAImpl.java:246)

at net.dv8tion.jda.api.JDABuilder.build(JDABuilder.java:1918)

at Main.main(Main.java:57)
Exception in thread "main" javax.security.auth.login.LoginException: The provided token is invalid!

at net.dv8tion.jda.internal.JDAImpl.verifyToken(JDAImpl.java:362)

at net.dv8tion.jda.internal.JDAImpl.login(JDAImpl.java:279)

at net.dv8tion.jda.internal.JDAImpl.login(JDAImpl.java:246)

at net.dv8tion.jda.api.JDABuilder.build(JDABuilder.java:1918)

at Main.main(Main.java:57)
So it would appear that this part from main function around the JDA part is having issues:
// bot
JDABuilder builder = JDABuilder.createDefault(Utility.readFromDatabase("TOKEN"));
// bot
JDABuilder builder = JDABuilder.createDefault(Utility.readFromDatabase("TOKEN"));
I have double checked that the TOKEN variable is the same locally and on the Postgres database, so the issue is not the token itself.
public static String readFromDatabase(String key) {
String sql = "SELECT value FROM config WHERE key = ?";

try (Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {

stmt.setString(1, key);

ResultSet rs = stmt.executeQuery();

if (rs.next()) {
return rs.getString("value");
}
} catch (SQLException e) {
System.out.println("Error: " + e.getMessage());
}

return null;
}
public static String readFromDatabase(String key) {
String sql = "SELECT value FROM config WHERE key = ?";

try (Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {

stmt.setString(1, key);

ResultSet rs = stmt.executeQuery();

if (rs.next()) {
return rs.getString("value");
}
} catch (SQLException e) {
System.out.println("Error: " + e.getMessage());
}

return null;
}
I can't seem to figure out what is wrong. And also, how can I use the deploy log to my advantage for debugging? Locally, sometimes i'll just do System.out.println to check variables, etc., but this does not show up in the deploy logs.
72 Replies
Percy
Percy16mo ago
Project ID: e202dece-bdd8-491e-810f-9d28bf4c36e6
bonjr
bonjrOP16mo ago
e202dece-bdd8-491e-810f-9d28bf4c36e6 Just realized I can use
private static Connection getConnection() throws SQLException {
String dbUrl = toJdbcUrl(System.getenv("DATABASE_URL"));

return DriverManager.getConnection(dbUrl);
}
private static Connection getConnection() throws SQLException {
String dbUrl = toJdbcUrl(System.getenv("DATABASE_URL"));

return DriverManager.getConnection(dbUrl);
}
for both dev and production, and once again, everything works fine locally, so something is going on with System.getenv on Railway
Brody
Brody16mo ago
show us your service variables please
bonjr
bonjrOP16mo ago
mullet.
mullet.16mo ago
Are you Sure this is a correct url? On some line in your code you check if the string starts with postgres:// Last I checked the one on your picture doesn't seem like it starts with that.
bonjr
bonjrOP16mo ago
my undersatanding is that System.getenv("DATABASE_URL") returns ${{Postgres.DATABASE_URL}}, which is pointing to this no?
bonjr
bonjrOP16mo ago
bonjr
bonjrOP16mo ago
and given this, it does indeed start with postgresql:// unless my understnding is wrong
mullet.
mullet.16mo ago
It seems like you have double postgres:// in the beginning but it might be wrong from my part Oh you have a worker and then a seperate service where you define the database. I think you might need to use shared variables?
bonjr
bonjrOP16mo ago
interesting, could you explain this? it's my first time on railway
mullet.
mullet.16mo ago
Scratch that. Seems like it would still work the way you have it. https://docs.railway.app/develop/variables#reference-variables
Railway Docs
Variables | Railway Docs
Documentation for Railway
ThallesComH
ThallesComH16mo ago
hi, did you make sure you can connect to your databse and that it's returning something? If it was the environment variable, Java would thrown a connection exception. You could also set your token in an environment variable to make sure that it's a database connection issue
bonjr
bonjrOP16mo ago
All I can say for sure is that when I run it locally, without changing the code at all, it all works fine. So it seems that it is possible to connect to the database and retrieve/set things as needed. But once I deploy it to Railway, that's when the ssues pop up i was just thinking abt trying this
ThallesComH
ThallesComH16mo ago
also, instead of parsing the connection string, you can separately set the credentials, make the code a lot cleaner.
Brody
Brody16mo ago
you are close, that is called a reference variable, it references the postgres plugins own DATABASE_URL variable, but while you see ${{Postgres.DATABASE_URL}} in the railway website, railway will replace that with the DATABASE_URL connection string from the database plugin when running your app do a console log of this please System.getenv("DATABASE_URL") however, you said you logs are not making it into the deployment logs, so make sure you are logging to stdout
bonjr
bonjrOP16mo ago
Yep, System.out.println() not showing up. I added some to the code and locally my console is flooded with the database_url (i put it inside the connection function) i pushed itto Railway, and log is not showing anything
Brody
Brody16mo ago
make sure you are logging to stdout
bonjr
bonjrOP16mo ago
also confirming not working even without databse private static Connection getConnection() throws SQLException { String dbUrl = toJdbcUrl(System.getenv("DATABASE_URL_ENV")); return DriverManager.getConnection(dbUrl); }
ThallesComH
ThallesComH16mo ago
send a screenshot of your logs
bonjr
bonjrOP16mo ago
i'm going to set up Log4J2 for this, give me a moment
bonjr
bonjrOP16mo ago
bonjr
bonjrOP16mo ago
ok deploying this version now
bonjr
bonjrOP16mo ago
nope
bonjr
bonjrOP16mo ago
trying logger.error as well now, let's see if that works...
Brody
Brody16mo ago
why don't you scroll up?
bonjr
bonjrOP16mo ago
oh this is the bottom? let me check how to scroll up lol
Brody
Brody16mo ago
with your scroll wheel?
bonjr
bonjrOP16mo ago
indeed 💀
bonjr
bonjrOP16mo ago
the top:
bonjr
bonjrOP16mo ago
thought you meant the section i was already scrolling was not the actual top of the file somehow, so thought the buttons at the bottom right were the answer, but they're just the scroll wheel as well hmm checking to see if dependencies are all good, gonna try something
Brody
Brody16mo ago
arent there a lot of errors there that you should worry about before you worry about printing a database variable?
bonjr
bonjrOP16mo ago
thing is i don't get any of those errors locally
Brody
Brody16mo ago
yeah but this isn't locally you need to make sure railway is running as close to as what you run locally what jdk and gradle versions do you use locally?
bonjr
bonjrOP16mo ago
Brody
Brody16mo ago
what gradle version
bonjr
bonjrOP16mo ago
switched from idea to vscode recently so checking where i can find it 1 sec also i'm using maven
Brody
Brody16mo ago
don't know what that is
bonjr
bonjrOP16mo ago
it's basically gradle but not, idk too in depth, just that you can pick either maven or gradle for build
Brody
Brody16mo ago
looks like railway will use maven then okay tell railway to use jdk 19 https://nixpacks.com/docs/providers/java
bonjr
bonjrOP16mo ago
ok
bonjr
bonjrOP16mo ago
possible closest thing i found to maven version
Brody
Brody16mo ago
dont know the default version of maven railway uses
bonjr
bonjrOP16mo ago
in intellij, so looks like it's 3.8.1
bonjr
bonjrOP16mo ago
messed around a bunch with dependencies, stackoverflow solutions, etc. all not working, still getting errors, but only when deployed... local is doing fine
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".

SLF4J: Defaulting to no-operation (NOP) logger implementation

SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

SLF4J: Failed to load class "org.slf4j.impl.StaticMDCBinder".

SLF4J: Defaulting to no-operation MDCAdapter implementation.

SLF4J: See http://www.slf4j.org/codes.html#no_static_mdc_binder for further details.

Exception in thread "main" javax.security.auth.login.LoginException: The provided token is invalid!

at net.dv8tion.jda.internal.JDAImpl.verifyToken(JDAImpl.java:362)

at net.dv8tion.jda.internal.JDAImpl.login(JDAImpl.java:279)

at net.dv8tion.jda.internal.JDAImpl.login(JDAImpl.java:246)

at net.dv8tion.jda.api.JDABuilder.build(JDABuilder.java:1918)

at Main.main(Main.java:57)
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".

SLF4J: Defaulting to no-operation (NOP) logger implementation

SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

SLF4J: Failed to load class "org.slf4j.impl.StaticMDCBinder".

SLF4J: Defaulting to no-operation MDCAdapter implementation.

SLF4J: See http://www.slf4j.org/codes.html#no_static_mdc_binder for further details.

Exception in thread "main" javax.security.auth.login.LoginException: The provided token is invalid!

at net.dv8tion.jda.internal.JDAImpl.verifyToken(JDAImpl.java:362)

at net.dv8tion.jda.internal.JDAImpl.login(JDAImpl.java:279)

at net.dv8tion.jda.internal.JDAImpl.login(JDAImpl.java:246)

at net.dv8tion.jda.api.JDABuilder.build(JDABuilder.java:1918)

at Main.main(Main.java:57)
and ofc the token will be invalid still because haven't figured out what is going on with the system.getenv()...
Brody
Brody16mo ago
dockerfile time!
bonjr
bonjrOP16mo ago
eh, i'm unfamiliar with it, any alternatives to railway?
Brody
Brody16mo ago
fly
bonjr
bonjrOP16mo ago
hmm alright i'll try that thanks for the help
Brody
Brody16mo ago
gotta tell me if you are able to deploy it on fly tho
bonjr
bonjrOP16mo ago
yeah i'll try and do it real quick rn see how far i get
bonjr
bonjrOP16mo ago
ok went on an adventue for sure... need to sleep too lmao BUT, having at some point messed around learning dockerfiles, i came back to Railway and now by using the dockerfileinstead, the only error i'm getting is this
ThallesComH
ThallesComH16mo ago
as the name suggests, it can't find your jarfile you can try to get a shell into the container locally to see where that jarfile is in docker run --entrypoint /bin/sh <image id>
bonjr
bonjrOP16mo ago
indeed.. currently trying to explicitly define it following this https://docs.railway.app/deploy/dockerfiles
Railway Docs
Dockerfiles | Railway Docs
Documentation for Railway
bonjr
bonjrOP16mo ago
um could you explain this? i know where the jar file is on my local machine, if i run that it will add something that will tell me where the jarfile is when it's built on Railway?
ThallesComH
ThallesComH16mo ago
it may differ the location on a dockerfile. you've docker installed in your machine right? if yes, you can build it docker build -t my-jda-bot . and then run the docker image but get a shell instead of actually running it docker run --rm --entrypoint /bin/sh my-jda-bot
bonjr
bonjrOP16mo ago
bonjr
bonjrOP16mo ago
why does Railway hate me 🤣 it's right there!
ThallesComH
ThallesComH16mo ago
it seems you're trying to run /target/<...>.jar
bonjr
bonjrOP16mo ago
isn't that where it's palced by default?
ThallesComH
ThallesComH16mo ago
not in this Dockerfile for some reason
bonjr
bonjrOP16mo ago
i'm lost ChikaConfused what do i need to do?
ThallesComH
ThallesComH16mo ago
isn't your jar inside /app? then change your Dockerfile to run that
bonjr
bonjrOP16mo ago
i think it is? CMD ["java", "-jar", "/app/TokenBot_1_maven-1.0-SNAPSHOT-jar-with-dependencies.jar"]
ThallesComH
ThallesComH16mo ago
yeah
bonjr
bonjrOP16mo ago
why is railway complaining 😭 😭 😭
bonjr
bonjrOP16mo ago
ok maybe huge development? why is it not reflecting on railway
bonjr
bonjrOP16mo ago
i swear i can see the finish line now https://docs.railway.app/deploy/config-as-code
Railway Docs
Config as Code | Railway Docs
Documentation for Railway
Brody
Brody16mo ago
you have the wrong idea, railway won't update the config as code with the CMD from your dockerfile, but I see another issue, your start command that youve set in the service settings is overriding the CMD command in the dockerfile, remove the start command from the service settings
bonjr
bonjrOP16mo ago
yeah i saw this setting after going the railway.json route i might delete the railway.json and go fix it up in the settings on railway instead but happy to report that after all this, it's finally working
Brody
Brody16mo ago
i take it your deployment to fly didnt go well?
bonjr
bonjrOP16mo ago
honestly can't even remember the full adventure i went on... was exploring fly.io and back4app, eventually forced to learn dockerfile somewhere, and for some reason ended up coming back to Railway but then Railway used my dockerfile and i noticed it was no longer giving those other errors and that's basically where my msgs start
Brody
Brody16mo ago
sounds good
Want results from more Discord servers?
Add your server