I am creating a Slack bot using Bolt framework in Java + Maven following this tutorial on their official website. My bot requires some keys that should be present as environment variables.
The application works just fine when I export those variables in the terminal prior to executing the application like this.
export SLACK_BOT_TOKEN=xoxb-...your-own-valid-one
export SLACK_SIGNING_SECRET=123abc...your-own-valid-one
mvn compile exec:java -Dexec.mainClass="hello.MyApp"
But when I don't, and instead save them in a .env file, the App constructor apparently doesn't get those keys even though I have loaded them in the main method from .env file.
Here is my main method:
package hello;
import com.slack.api.bolt.App;
import com.slack.api.bolt.jetty.SlackAppServer;
import io.github.cdimascio.dotenv.Dotenv;
public class MyApp {
public static void main(String[] args) throws Exception
{
Dotenv dotenv = Dotenv.configure().directory("./").load();
System.out.println(dotenv.get("SLACK_BOT_TOKEN"));
System.out.println(dotenv.get("SLACK_SIGNING_SECRET"));
// CREATING THE SLACK APP
App slackApp = new App();
slackApp.command("/mytesthello", (req, ctx)-> {
return ctx.ack(":wave: Hello!");
});
SlackAppServer slackAppServer = new SlackAppServer(slackApp);
slackAppServer.start();
}
}
The console is able to show the correct output using System.out.println indicating that the variables are accessible, but most probably the App() constructor is not able to get them, since whenever I try to make POST request from my slack app, the ngrok interface as well as my terminal show unauthorized access. (again, this is the case when I don't export the environment variables)
What should I do to make sure that the environment variables are available from .env file? Otherwise it would be very cumbersome to keep exporting them whenever I run the application.
Related
We have a spring boot web application that we start with a modified, extended start command similar to this:
java -classpath "..." -Dlogging.config="..." org.springframework.boot.loader.JarLauncher --debug --spring.config.location="..."
Now, we need to restart this application programatically (e.g. via an endpoint), but we need to ensure that the "same start command is used".
I found this solution on bealdung:
#SpringBootApplication
public class Application {
private static ConfigurableApplicationContext context;
public static void main(String[] args) {
context = SpringApplication.run(Application.class, args);
}
public static void restart() {
ApplicationArguments args = context.getBean(ApplicationArguments.class);
Thread thread = new Thread(() -> {
context.close();
context = SpringApplication.run(Application.class, args.getSourceArgs());
});
thread.setDaemon(false);
thread.start();
}
}
In this case, the program arguments can be extracted with the bean ApplicationArguments.
So far I did not find a way to do the same for VM arguments and also the extension of the classpath as seen in the command above.
Is that even possible? Is there a more convenient way to restart a spring boot application with all these requirements in mind?
The way you've found in tutorial does not restart the whole JVM process, it closes the application context and re-creates it. This means that all the beans get loaded again which is logically equivalent to restart as far as all the objects are managed by Spring or course.
There as also a way of making such a restart without writing custom code - use Spring Boot's actuator that has a restart endpoint. You can invoke the endpoint and the application will be restarted in the same sense as you've described. See this tutorial for example there are many others.
In both of the ways, there will be the same JVM process (jvm does not restart), so both classpath and JVM parameters will remain just the same (do not change).
So if you want to restart the JVM you can wrap the long command into some sort of script (like bash if you're working on linux, or *.bat file for windows for example).
Other than that spring boot can't help much - from this perspective its a regular java application.
I'm trying to execute a simple java code.
the code worked fine using comand line : javac Go.java and java Go, but in Spring Tool Suite 3, the code did not work and I got the error below.
Note that I'm using jdk1.8.0_211
package com.test;
public class Go {
public static void main(String[] args) {
System.out.println("test");
}
}
I expect print test, but I get this error :
Error: Can not find or load the main class.
the cause of the problem is that I'm not the owner of the Laptop, it is managed by the administrator of the company where I work. I noticed that when I change the version of JAVA, the code runs correctly, but after restarting the Laptop, I get the same error again, so the cause was that every restart of the laptop, it updates java version, I fixed my PC to not updating java version again and it works
I have a dropwizard question. I use Dropwizard with SBT (which works pretty fine).
If I run my application i package it with:
$ sbt clean assembly
And than run the application with:
$ java -jar APPLICATION.jar server
The problem is with this command Dropwizard doesnt load my config file (config.yaml), which is in the resources located.
Regarding the Dropwizard Docs I always have to give the config file as parameter like:
$ java -jar APPLICATION.jar server config.yaml
This works fine and it loads the application but is there any possibility to tell Dropwizard to load directly the config.yaml file, because my configuration in the config.yaml file is static and it is always the same. Settings like Database etc which are changing from Server Stage to Server Stage are made as Enviroment Variable which I load with EnvironmentVariableSubstitutor.
Thanks
Use class ResourceConfigurationSourceProvider:
#Override
public void initialize(final Bootstrap<ExampleConfiguration> bootstrap) {
bootstrap.setConfigurationSourceProvider(new ResourceConfigurationSourceProvider());
// The rest of initialize...
}
And then invoke the application like:
java -jar APPLICATION.jar server /resource-config.yaml
(note the initial /)
While this answer is very late, just thought I'd put this here. There is a dirty little hack to make it work so that you don't have to provide config.yaml in your application arguments.
Basically, you can submit a new String[] args to the run() method in the dropwizard application.
public class ApplicationServer extends Application<Config> {
public static void main(String[] args) {
String[] appArgs = new String[2];
appArgs[0] = args[0]; // This will be the usual server argument
appArgs[1] = "config.yaml";
new ApplicationServer().run(appArgs);
}
#Override
public void run(Config configuration, Environment environment) {
// Configure your resources and other application related things
}
}
I used this little trick to specify which config file I wanted to run with. So instead of specifying config.yaml, I would give my second argument as DEV/UAT/STAGE/PROD and pass on the appropriate config file to the run method.
Also interesting to have a look at:
earlye/dropwizard-multi-config
<dependency>
<groupId>com.thenewentity</groupId>
<artifactId>dropwizard-multi-config</artifactId>
<version>{version}</version>
</dependency>
It allows overriding and merging multiple config-files passed on the java command-line like:
java -jar sample.jar server -- sample.yaml override.yaml
Here you pass (1) sample.yaml as the primary configuration (e.g. having default values) and (2) override.yaml as the override. The effective config is a result from merging both in order of appearance: (1) defaults will be overwritten and merged with (2).
I already install jco3 for linux.
I'm using ubuntu 16.04 x86_64 and java-8-oracle
as the documentation said, i need to add LD_LIBRARY_PATH and CLASSPATH to jco directory.
export LD_LIBRARY_PATH=/home/zain/sapjco
export CLASSPATH=/home/zain/sapjco/sapjco3.jar
then create simple jco connection test
import com.sap.conn.jco.*;
public class testjco {
public static void main(String[] args) {
JCO.Client mConnection;
try {
mConnection = JCO.createClient("301", // SAP client
"somecoolguy", // userid
"****", // password
"EN", // language
"XXX", // application server host name
"00"); // system number
mConnection.connect();
System.out.println(mConnection.getAttributes());
mConnection.disconnect();
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
}
but when i run my project i got error
error: package com.sap.conn.jco does not exist
is there any particular step i missed?
I don't know if you've already done this but:
export LD_LIBRARY_PATH=/home/zain/sapjco
export CLASSPATH=/home/zain/sapjco/sapjco3.jar
only work in the current bash instance, which means that if you ever close that terminal window then that export path will be gone. One way to keep it is to add it to your ~/.profile
then you can just run this source ~/.bashrc in order to refresh your bash window.
Don't know if that helped since I have never coded Java in Ubuntu, only on Mac with Eclipse/Idea. Anyways, if that's not how to do it, then there's a problem with the way you imported your sapjco3.jar to your project.
You also need to use your CLASSPATH environment variable and pass it as classpath argument to your JVM instance that shall run your project.
But I don't think that you are really at the step of running your project, you must be already failing to compile your class testjco. (By the way, I recommend to follow the common Java naming conventions and let all class names start with an uppercase letter.)
You are importing the package com.sap.conn.jco which belongs to the SAP Java Connector 3.0 (sapjco3.jar), but in your code you use the JCo API from package com.sap.mw.jco of the outdated SAP Java Connector 2.0/2.1 (sapjco.jar). That does not work and cannot be compiled.
I have a problem with running simple JavaFX application. I'm using native packager to build exe. I want to run my application from windows file context menu, but when I try to run application with params:
> JavaFXApplication1.exe ąęć
and i'm getting 2 errors:
1) , and after click "OK":
2)
When i run application as jar file:
> java -jar JavaFXApplication1.jar ąęć
Application started with success and it's working fine.
Also, when I run application from this command:
> JavaFXApplication1.exe aec
everything is ok and application's working fine.
Example application code:
package test;
import javafx.application.Application;
import javafx.stage.Stage;
public class Test extends Application {
#Override
public void start(Stage primaryStage) {
System.out.println("Started");
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Args count: " + args.length);
launch(args);
}
}
Ignore, that application doesn't close.
I think that it's exactly the same problem as described here: https://bugs.openjdk.java.net/browse/JDK-8133034
Did somebody resolve this? Or is there someone, who knows a workaround of this problem? I tried java versions from 1.8.40 up to 1.8.72, but it failed on each JVM. It's also not a enviroment problem, because i've tested it on 2 different machines (and also operating systems).
I would appreciate any help.
The Jira issue mentions in a comment that it is a regression starting JDK version 8u40b06. If possible one workaround is to use an older one. Try 8u40b05.
For the moment, maybe you can store all command arguments in a file (named in ASCII characters) and pass the file location as an argument in order to read the actual arguments of the application.
Another workaround (last resort?) is to pass characters as escaped Unicode. See Convert escaped Unicode character back to actual character. Although admittedly it's an ugly and tedious thing to do.