Websphere Console 9.0 - where to specify Application specific files paths in websphere console - websphere

Websphere version 9.0 is installed in our RHEL 8.3 OS .
Now in that i have deployed one web app - .war file which contains multiple modules - webservice, web module etc.
This war is successfully deployed and i am able to start it also going to Websphere Enterprise Applications - AppName - START.
The app gets started with a success message.
Now the problem lies ahead. Our application requires a certain file bootstrap.properties.
This file has several configurations like jdbc params, jmx ports, jms configurations, jvm arguments, logging paths etc.
Once the web module of this app is run on <SERVER_IP>:9080/Context url, it throws error on GUI saying Unable to locate bootstrap.properties.
Analysing at the code level , found out that below code is throwing this error:
private static Properties config;
private static final String CONFIG_ROOT = System.getProperty("bootstrap.system.propertiespath");
private static final String configFile = "bootstrap.properties";
private JMXConfig() {
}
public static String getConfigRoot() {
if (CONFIG_ROOT == null) {
System.err.println("Not able to locate bootstrap.properties. Please configure bootstrap.system.propertiespath property.");
throw new ConfigException("Unable to locate bootstrap.properties.");
} else {
return CONFIG_ROOT + File.separator;
}
}
I wanted to know where can we specify the absolute paths in the websphere console where our property file can be read as a system argument once the application is loaded.

Since you're using System.getProperty() to read the property, it needs to be specified as a Java system property passed into the JVM. You can do that from the JVM config panel, adding it as either a custom property on the JVM or as a -D option in the server's generic JVM arguments.
Custom property: https://www.ibm.com/docs/en/was/9.0.5?topic=jvm-java-virtual-machine-custom-properties
Generic JVM argument: https://www.ibm.com/docs/en/was/9.0.5?topic=jvm-java-virtual-machine-settings (search for "Generic JVM arguments")
Note that if you use a custom property, you would simply set the "name" field to "bootstrap.system.propertiespath" and the "value" to the path you need; if you use a generic JVM argument, you'd add an argument with the structure "-Dbootstrap.system.propertiespath=/path/to/file".

Related

override command line Spring properties with bootstrap.yml

i have a tomcat box , which has spring active profile set already, as a command line argument every time a spring app is deployed through catalina.
i am using spring cloud config server , so in config client i specify active profile in bootstrap.yml , but as i mention earlier it is overriden by tomcat command line argument .
how to override the command line argument passed through tomcat , with my boostrap.yml at the time of bootstrap context loading so that i can pass active profile from my bootstrap.yml to config server.
Tomcat set environment command (which i cannot change as i dont have access)
JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/path -Dspring.profiles.active=e2"
bootstrap.yml
spring:
profiles:
active: e2,cron
cloud:
config:
uri: http://localhost:8888
application:
name: heartbeat_monitor.
Command line argument(-Dspring.profiles.active=e2) will always override your properties file, no matter how many hardcoded profiles you specify in your yaml file. I would suggest you to add additional profile to be set programatically at the runtime and keep two property files with -profilename before the .yml extension.
This could be done as follows:
ApplicationMain.java
public static void main(String[] args) {
SpringApplication app = new SpringApplication(DemoApplication.class);
app.setAdditionalProfiles("cron");
app.run(args);
}
bootstrap-e2.yml
// Keep all the properties which is specific to e2 profile.
bootstrap-cron.yml
// Keep all the properties which is specific to cron profile.
In this way, you can keep both the profiles in use .But, if a property is common in both the bootstrap files, then program will pick the property from that bootstrap file whose profile matches with the runtime args : -Dspring.profiles.active

Spring ignores `spring.cloud.config.discovery` set as default properties

I'm trying to create Spring Application without referring to any external files. This is supposed to be a module that you'd then include as a dependency, configure and use to plug in the service into an existing ecosystem. This is how I'm doing that:
Map<String, Object> properties = new HashMap<>();
properties.put("server.address", "0.0.0.0")
properties.put("server.port", 8080)
properties.put("spring.profiles.active", "cloud")
properties.put("spring.application.name", "someApp")
properties.put("spring.cloud.config.failFast", true)
properties.put("spring.cloud.config.discovery.enabled", true)
properties.put("spring.cloud.config.discovery.serviceId", "config")
properties.put("eureka.instance.preferIpAddress", true)
properties.put("eureka.instance.statusPageUrlPath", "/health")
new SpringApplicationBuilder()
.bannerMode(Banner.Mode.OFF)
.properties(properties)
.sources(SpringConfiguration.class)
.web(false)
.registerShutdownHook(true)
.build()
I then go on to provide Eureka default zone in the run command, via environmental variables:
--env eureka_client_serviceUrl_defaultZone='http://some-host:8765/eureka/' --env SPRING_CLOUD_CONFIG_LABEL='dev' --env SPRING_CLOUD_INETUTILS_PREFERRED_NETWORKS='10.0'
Application registers successfully in Eureka, but unfortunately it tries to fetch the config prior to that and it's looking for it under the default URL (http://localhost:8888) instead of fetching config server IP from the registry. And yes, it does work if I put all of those properties in the bootstrap.yml file. Can I somehow make it work without using file-resources?
You are passing the properties using SpringApplicationBuilder which is responsible for SpringApplication and ApplicationContext instances.
From the documentation , the properties provided here will be part of ApplicationContext NOT the BootstrapContext. ApplicationContext is the child of BootstrapContext.
You can read more about the Bootstrap Context here -
http://cloud.spring.io/spring-cloud-commons/1.3.x/single/spring-cloud-commons.html#_the_bootstrap_application_context
Bootstrap.yml/properties is used to configure your Bootstrap Context.
You can look at these properties to change the name or location of the file -
spring.cloud.bootstrap.name - bootstrap(default)
spring.cloud.bootstrap.location
You will have to use a file resource(yml or properties).

self hosted vnext application

I was wondering if I could refactor a self-hosted app (console app that starts and displays the URL of the webservices it provides) for it to work on pure vnext instead of owin.
The owin code is the following
namespace Selfhostingtest
{
class Program
{
static void Main(string[] args)
{
String strHostName = string.Empty;
strHostName = Dns.GetHostName();
Console.WriteLine("Local Machine's Host Name: " + strHostName);
var options = new StartOptions();
IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;
for (int i = 0; i < addr.Length; i++)
{
if (!addr[i].IsIPv6LinkLocal && addr[i].AddressFamily == AddressFamily.InterNetwork)
{
Console.WriteLine("IPv4 Address {0}: {1} ", i, addr[i].ToString());
options.Urls.Add(String.Format("http://{0}:5000/", addr[i].ToString()));
}
}
using (WebApp.Start<Startup>(options))
{
Console.WriteLine("Razor server is running. Press enter to shut down...");
Console.ReadLine();
}
}
}
}
For the record, I don't want to use the "k web" command line start. I want to fully package the vnext app as an executable file.
Instead of Microsoft.Owin.Hosting, the Microsoft.AspNet.Hosting should be used (same class as in the "k web" command definition. Keep in mind that Owin Startup expects IAppBuilder and the vnext expects IBuilder.
In ASP.NET vNext you cannot build an EXE file, but you can definitely package up an app to be self-contained. Check out the kpm pack command that you can run in your app's folder. It will package up all the dependencies as well as generate the command scripts that you can use (instead of using k web etc.). Ultimately if you look at what k web does, it's just some shell scripts that end up running klr.exe with various parameters to indicate what it should start.
The project wiki has some basic information on the kpm tool's various options: https://github.com/aspnet/Home/wiki/Package-Manager
Here is the command line help for kpm pack to give you an idea of what it can do.
Usage: kpm pack [arguments] [options]
Arguments:
[project] Path to project, default is current directory
Options:
-o|--out <PATH> Where does it go
--configuration <CONFIGURATION> The configuration to use for deployment
--overwrite Remove existing files in target folders
--no-source Don't include sources of project dependencies
--runtime <KRE> Names or paths to KRE files to include
--appfolder <NAME> Determine the name of the application primary folder
-?|-h|--help Show help information

Spring Boot Yarn - Passing Command line arguments

i'm trying to pass command line arguments in my Spring Boot Yarn application and am having difficulties. i understand that i can set these in the yml document spring.yarn.appmaster.launchcontext.arguments but how can it from the command line? like java -jar MyYarnApp.jar {arg0} {arg1} and get access to it from my #YarnContainer?
i've discovered that #YarnProperties maps to spring.yarn.appmaster.launchcontext.arguments but i want to set them from the command line, not in the yml
You are pretty close on this when you found spring.yarn.client.launchcontext.arguments and spring.yarn.appmaster.launchcontext.arguments. We don't have settings which would automatically pass all command-line arguments from a client into an appmaster which would then pass them into a container launch context. Not sure if we even want to do that because you surely want to be on control what happens with YARN container launch context. User using a client could then potentially pass a rogue arguments along a food chain.
Having said that, lets see what we can do with our Simple Single Project YARN Application Guide.
We still need to use those launch context arguments to define our command line parameters to basically map how things are passed from a client into an appmaster into a container.
What I added in application.yml:
spring:
yarn:
client:
launchcontext:
arguments:
--my.appmaster.arg1: ${my.client.arg1:notset1}
appmaster:
launchcontext:
arguments:
--my.container.arg1: ${my.appmaster.arg1:notset2}
Modified HelloPojo in Application class:
#YarnComponent
#Profile("container")
public static class HelloPojo {
private static final Log log = LogFactory.getLog(HelloPojo.class);
#Autowired
private Configuration configuration;
#Value("${my.container.arg1}")
private String arg1;
#OnContainerStart
public void onStart() throws Exception {
log.info("Hello from HelloPojo");
log.info("Container arg1 value is " + arg1);
log.info("About to list from hdfs root content");
FsShell shell = new FsShell(configuration);
for (FileStatus s : shell.ls(false, "/")) {
log.info(s);
}
shell.close();
}
}
Notice how I added arg1 and used #Value to map it with my.container.arg1. We can either use #ConfigurationProperties or #Value which are normal Spring and Spring Boot functionalities and there's more in Boot's reference docs how to use those.
You could then modify AppIT unit test:
ApplicationInfo info = submitApplicationAndWait(Application.class, new String[]{"--my.client.arg1=arg1value"});
and run build with tests
./gradlew clean build
or just build it without running test:
./gradlew clean build -x test
and then submit into a real hadoop cluster with your my.client.arg1.
java -jar build/libs/gs-yarn-basic-single-0.1.0.jar --my.client.arg1=arg1value
Either way you see arg1value logged in container logs:
[2014-07-18 08:49:09.802] boot - 2003 INFO [main] --- ContainerLauncherRunner: Running YarnContainer with parameters [--spring.profiles.active=container,--my.container.arg1=arg1value]
[2014-07-18 08:49:09.806] boot - 2003 INFO [main] --- Application$HelloPojo: Container arg1 value is arg1value
Using format ${my.client.arg1:notset1} also allows you to automatically define a default value notset1 if my.client.arg1 is omitted by user. We're working on Spring Application Context here orchestrated by Spring Boot so all the goodies from there are in your disposal
If you need more precise control of those user facing arguments(using args4j, jopt, etc) then you'd need to have a separate code/jar for client/appmaster/container order to create a custom client main method. All the other Spring YARN getting started guides are pretty much using multi-project builds so look at those. For example if you just want to have first and second argument value without having a need to use full --my.client.arg1=arg1value on a command line.
Let us know if this works for you and if you have any other ideas to make things simpler.

Embedded Glassfish v3: deploying sun-resources.xml programmatically fails

I would like to be able to package my jpa-ejb-web project as a standalone application, by using Glassfish embedded API.
To use the JPA layer, I need to deploy the sun-resource.xml configuration, which should be possible with the asadmin command add-resources path\to\sun-resources.xml. I've this code to do it:
String command = "add-resources";
ParameterMap params = new ParameterMap();
params.add("", "...\sun-resources.xml" );
CommandRunner runner = server.getHabitat().getComponent(CommandRunner.class);
ActionReport report = server.getHabitat().getComponent(ActionReport.class);
runner.getCommandInvocation(command, report).parameters(params).execute();
but Glassfish refuses it with:
15-Jul-2010 16:34:12 org.glassfish.admin.cli.resources.AddResources execute
SEVERE: Something went wrong in add-resources
java.lang.Exception: ...\gfembed6930201441546233570tmp\lib\dtds\sun-resources_1_4.dtd (The system cannot find the path specified)
at org.glassfish.admin.cli.resources.ResourcesXMLParser.initProperties(ResourcesXMLParser.java:163)
at org.glassfish.admin.cli.resources.ResourcesXMLParser.<init>(ResourcesXMLParser.java:109)
at org.glassfish.admin.cli.resources.ResourcesManager.createResources(ResourcesManager.java:67)
at org.glassfish.admin.cli.resources.AddResources.execute(AddResources.java:106)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:305)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:320)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1176)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$900(CommandRunnerImpl.java:83)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1235)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1224)
at javaapplication4.Main.main(Main.java:55)
and indeed, there is no lib directory on the indicated path ...
is there something wrong in my code? (I use glassfish-embedded-all-3.0.1.jar)
Thanks
I solved it by specifying an Embedded File System for the embedded Glassfish, and prepopulated the /path/to/my/glassfish/lib/dtds folder with the files which were missing.
EmbeddedFileSystem.Builder efsb = new EmbeddedFileSystem.Builder();
efsb.autoDelete(false);
efsb.installRoot(new File("/path/to/my/glassfish"), true);
EmbeddedFileSystem efs = efsb.build();
Server.Builder builder = new Server.Builder("test");
builder.embeddedFileSystem(efs);
builder.logger(true);
Server server = builder.build();
server.addContainer(ContainerBuilder.Type.all);
server.start();
and asking Glassfish not to delete the folder at the end of the execution.
I'm not sure this is possible, Running asadmin Commands Using the Sun GlassFish Embedded Server API doesn't mention such a use case (passing a sun-resources.xml).
But I would use a preconfigured domain.xml instead of trying to deploy a sun-resource.xml file, the result should be similar. From the Sun GlassFish Enterprise Server v3 Embedded Server Guide:
Using an Existing domain.xml File
Using an existing domain.xml file
avoids the need to configure embedded
Enterprise Server programmatically in
your application. Your application
obtains domain configuration data from
an existing domain.xml file. You can
create this file by using the
administrative interfaces of an
installation of nonembedded Enterprise
Server. To specify an existing
domain.xml file, invoke the
installRoot, instanceRoot, or
configurationFile method of the
EmbeddedFileSystem.Builder class or
a combination of these methods.
The documentation provides code samples showing how to do this (should be pretty straightforward).

Resources