I am trying to read properties file to fetch the values. But, the code is throwing an exception.
Exception
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.cisco.installbase.hiveconnector.ReadProperties.getInstance(ReadProperties.java:28)
at com.cisco.installbase.hiveconnector.MainApp.main(MainApp.java:7)
Caused by: java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:434)
at java.util.Properties.load0(Properties.java:353)
at java.util.Properties.load(Properties.java:341)
at com.cisco.installbase.hiveconnector.ReadProperties.<init>(ReadProperties.java:16)
at com.cisco.installbase.hiveconnector.ReadProperties.<init>(ReadProperties.java:12)
at com.cisco.installbase.hiveconnector.ReadProperties$PropHolder.<clinit>(ReadProperties.java:23)
... 2 more
ReadProperties.java
package com.cisco.installbase.hiveconnector;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Set;
public class ReadProperties {
private final Properties props = new Properties();
private ReadProperties()
{
InputStream in = this.getClass().getClassLoader().getResourceAsStream("config.properties");
try{
props.load(in);
}catch(IOException e){
e.printStackTrace();
}
}
private static class PropHolder{
private static final ReadProperties INSTANCE = new ReadProperties();
}
public static ReadProperties getInstance()
{
return PropHolder.INSTANCE;
}
public String getProperty(String key)
{
return props.getProperty(key);
}
public Set<String> getAllPropertyNames()
{
return props.stringPropertyNames();
}
public boolean containsKey(String key)
{
return props.containsKey(key);
}
}
the directory structure and location of my prop file
Can someone help me with the location where the property file needs to be put.
Your file config.properties is not on classpath, therefore cannot be loaded via this.getClass().getClassLoader().getResourceAsStream("config.properties")
Put it under src/main/resources
Please consult the Standard Maven directory layout
If this is a typical maven project then the properties file goes under src/main/resources. Maven will move it into the classpath for you.
Related
I made a structure change in my project, and I am getting this error
Project Structure:
enter image description here
the platform notifies me of the following error:
Step failed
java.lang.NullPointerException: inStream parameter is null
at java.base/java.util.Objects.requireNonNull(Objects.java:233)
at java.base/java.util.Properties.load(Properties.java:407)
at com.crm.framework.config.ConfigReader.ReadProperty(ConfigReader.java:19)
at com.crm.framework.config.ConfigReader.PopulateSettings(ConfigReader.java:11)
at steps.TestInitialize.Initialize(TestInitialize.java:21)
This is my ConfigReader, which is shown in the above error
ConfigReader:
package com.crm.framework.config;
import com.crm.framework.base.BrowserType;
import java.io.IOException;
import java.util.Properties;
public class ConfigReader {
public static void PopulateSettings() throws IOException {
ConfigReader reader = new ConfigReader();
reader.ReadProperty();
}
private void ReadProperty() throws IOException {
//Create Property Object
Properties p = new Properties();
//Load the property file available in same package
p.load(getClass().getResourceAsStream("GlobalConfig.properties"));
//Get AUTConnection String
Settings.AUTConnectionString = p.getProperty("AUTConnectionString");
//Get Reporting String
Settings.ReportingConnectionString = p.getProperty("ReportingConnectionString");
//Get LogPath
Settings.LogPath = p.getProperty("LogPath");
//Get DriverType
Settings.DriverType = p.getProperty("DriverType");
//Get ExcelSheetPath
Settings.ExcelSheetPath = p.getProperty("ExcelSheetPath");
//Get AUT
Settings.AUT = p.getProperty("AUT");
//Browser Type
Settings.BrowserType = BrowserType.valueOf(p.getProperty("BrowserType"));
}
}
I also attach the code of the TestInitialize, file that contains the #Before to run the test cases
TestInitialize:
package steps;
import com.crm.framework.base.DriverContext;
import com.crm.framework.base.FrameworkInitialize;
import com.crm.framework.config.ConfigReader;
import com.crm.framework.config.Settings;
import com.crm.framework.utilities.LogUtil;
import io.cucumber.java.Before;
// import io.cucumber.java.Before;
import java.io.IOException;
public class TestInitialize extends FrameworkInitialize {
#Before
public void Initialize() throws IOException {
//Initialize config
ConfigReader.PopulateSettings();
//Logging
Settings.Logs = new LogUtil();
Settings.Logs.CreateLogFile();
Settings.Logs.Write("Framework initialize");
//Create Test Cycle for Reporting
/*
Pending
*/
Settings.Logs.Write("Test Cycle Created");
InitializeBrowser(Settings.BrowserType);
Settings.Logs.Write("Browser initialize");
DriverContext.Browser.GotoUrl(Settings.AUT);
Settings.Logs.Write("Navigate to URL: " + Settings.AUT);
}
}
Here is the most likely culprit:
https://docs.oracle.com/javase/10/docs/api/java/util/Properties.html#getProperty(java.lang.String)
From Javadoc:
public String getProperty​(String key)
Searches for the property with the specified key in this property list. If the key is not found in
this property list, the default property list, and its defaults,
recursively, are then checked. The method returns null if the property
is not found.
Properties are case sensitive. Make sure that:
The property file you need exists, then
The property key inside the file exists and lastly
It is spelled out the exact same way it appears in the file.
As a failsafe, you could use getProperty(key, defaultValue)which it is similar to the one above, except that it returns the passed default value instead of null in cases where the property key being passed to the method doesn't exist in the given property file.
Also, make sure the PATH to the property file is correct. Understanding how file paths are resolved when running from IDE and from deploy environment could also be an issue if you don't understand how resources are resolved.
I have created a WebApp test automation framework for my project on my local machine using Maven, Java and TestNG frameworks. We have TeamCity in our CI/CD and my team would like the framework to use TeamCity's environment variables (including username and pass to the WebApp under test) instead porperties hard coded in my projects 'configuration.properties' file.
The mechanism used in my project when it comes to properties configuration is as follows:
- resources package which contains 'configuration.properties' file. This file contains variables such as app.url, browser, chrome.driver.location.
- 'configuration.properties' file is then read by classes in configuration package. Classes are as follows: AppProperties.java, ConfigurationProperties.java, PropertiesLoader.java, LocalWebDriverPorperties.java and TestRunProperties .java classes
Configuration.properties
app.url=url for app under test
is.remote.run=false
grid.url="";
browser=CHROME
chrome.driver.location=C:/Selenium/chromedriver.exe
firefox.driver.location=C:/Selenium/geckodriver.exe
AppProperties.java
package configuration;
public class AppProperties {
public static String getAllUrl() {
return ConfigurationProperties.getProperties().getProperty("app.url");
}
}
ConfigurationProperties.java
package configuration;
import java.util.Properties;
public class ConfigurationProperties {
private static Properties properties;
private ConfigurationProperties() {
}
public static void setProperties(Properties properties) {
ConfigurationProperties.properties = properties;
}
public static Properties getProperties() {
if (properties == null) {
throw new IllegalStateException("Please set properties using setProperties() before calling getProperties()");
}
return properties;
}
}
PropertiesLoader.java
package configuration;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesLoader {
private Logger logger = LogManager.getLogger(PropertiesLoader.class);
public Properties getPropertiesFromFile(String propertiesFileName) {
InputStream inputStream = null;
Properties properties = new Properties();
try {
logger.info("Trying to load properties with file name: " + propertiesFileName);
inputStream = getClass().getClassLoader().getResourceAsStream(propertiesFileName);
if (inputStream != null) {
properties.load(inputStream);
logger.info("Successfully loaded properties for file: " + propertiesFileName);
} else {
throw new FileNotFoundException("Property file '" + propertiesFileName + "' not found in the classpath");
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Cannot load properties due to IOException!");
} finally {
closeResource(inputStream);
}
return properties;
}
private void closeResource(InputStream inputStream) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
LocalWebDriverProperties.java
package configuration;
public class LocalWebDriverProperties {
return BrowserType.valueOf(ConfigurationProperties.getProperties().getProperty("browser"));
// }
public static String getChromeWebDriverLocation() {
return ConfigurationProperties.getProperties().getProperty("chrome.driver.location");
}
public static String getFirefoxWebDriverLocation() {
return ConfigurationProperties.getProperties().getProperty("firefox.driver.location");
}
public static String getInternetExplorerWebDriverLocation() {
return ConfigurationProperties.getProperties().getProperty("ie.driver.location");
}
}
TestRunProperties.java
package configuration;
import driver.manager.BrowserType;
public class TestRunProperties {
public static String getGridUrl() {
return ConfigurationProperties.getProperties().getProperty("grid.url");
}
public static BrowserType getBrowserToRun() {
return BrowserType.valueOf(ConfigurationProperties.getProperties().getProperty("browser"));
}
public static boolean getIsRemoteRun(){
return Boolean.parseBoolean(ConfigurationProperties.getProperties().getProperty("is.remote.run"));
}
}
The above configuration works fine if i specify server properties like (app.url, browser) used by Team City server in configuration.properties file of the framework.
But what i am looking for is to use a different approach and instead of having properties set up in configuration.properties file- use an environment variables of TeamCity.
Probably having this functionality in one class like AppProperties.java instead of using 5 classes as I am doing at the moment.
Is there any way to do this?
I've looked at all kinds of answers for this problem. None of them work.
I have the following code:
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ApplicationConfig {
private static Logger LOG;
private String appConfigFileLocation = "application.properties";
private Properties appConfig;
private static ApplicationConfig instance;
public static ApplicationConfig getInstance() {
if(instance == null) {
instance = new ApplicationConfig();
}
return instance;
}
private ApplicationConfig() {
LOG = LoggerFactory.getLogger(this.getClass().getSimpleName());
appConfig = new Properties();
try {
LOG.info("Reading config from " + appConfigFileLocation);
appConfig.load(ClassLoader.getSystemResourceAsStream(appConfigFileLocation));
LOG.info("Done reading config from " + appConfigFileLocation);
} catch (FileNotFoundException e) {
LOG.error("Encountered FileNotFoundException while reading configuration: " + e.getMessage());
throw new RuntimeException(e);
} catch (IOException e) {
LOG.error("Encountered IOException while reading configuration: " + e.getMessage());
throw new RuntimeException(e);
}
}
}
I created a JAR file. The JAR file has application.properties at the root. I also copied the application.properties file in /etc/hadoop/conf and in the target/classes/ directory.
I use the hadoop jar command to execute the code.
But I keep getting the error: java.lang.NullPointerException at java.util.Properties$LineReader.readLine(Properties.java:434)
Please help me at resolving this frustrating error!
Found the error.
hadoop jar checks in the Hadoop classpath. Even though the file was there in the Hadoop classpath, it didn't have read permissions from the Hadoop user.
A simple sudo chmod a+r /etc/hadoop/conf/application.properties did the trick!
I use the JDOM library. When I write information into an xml file, Eclipse shows errors. The system cannot find the path specified. I try to create the file in the "language" folder. How can I create the folder automatically when I write info into this file? I think the error is in this line:
FileWriter writer = new FileWriter("language/variants.xml");
Here is my code:
package test;
import java.io.FileWriter;
import java.util.LinkedList;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
class Test {
private LinkedList<String> variants = new LinkedList<String>();
public Test() {
}
public void write() {
Element variantsElement = new Element("variants");
Document myDocument = new Document(variantsElement);
int counter = variants.size();
for(int i = 0;i < counter;i++) {
Element variant = new Element("variant");
variant.setAttribute(new Attribute("name",variants.pop()));
variantsElement.addContent(variant);
}
try {
FileWriter writer = new FileWriter("language/variants.xml");
XMLOutputter outputter = new XMLOutputter();
outputter.setFormat(Format.getPrettyFormat());
outputter.output(myDocument,writer);
writer.close();
}
catch(java.io.IOException exception) {
exception.printStackTrace();
}
}
public LinkedList<String> getVariants() {
return variants;
}
}
public class MyApp {
public static void main(String[] args) {
Test choice = new Test();
choice.write();
}
}
Here is the error:
java.io.FileNotFoundException: language\variants.xml (The system cannot find the path specified)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
at java.io.FileOutputStream.<init>(FileOutputStream.java:104)
at java.io.FileWriter.<init>(FileWriter.java:63)
at test.Test.write(MyApp.java:31)
at test.MyApp.main(MyApp.java:49)`enter code here
As the name suggests FileWriter is for writing to file. You need to create the directory first if it doesnt already exist:
File theDir = new File("language");
if (!theDir.exists()) {
boolean result = theDir.mkdir();
// Use result...
}
FileWriter writer = ...
For creating directories you need to use mkdir() of File class.
Example:
File f = new File("/home/user/newFolder");
f.mkdir();
It returns a boolean: true if directory created and false if it failed.
mkdir() also throws Security Exception if security manager exists and it's checkWrite() method doesn't allow the named directory to be created.
PS: Before creating directory, you need to validate if this directory already exists or not by using exists() which also returns boolean.
Regards...
Mr.777
Something is wrong and it is very frustrating. I read on velocity's homepage that when I run a webapp then some properties should be set. And I've done that but no matter what I do I keep getting the same error.
This is where I set the props and use velocity
public class ConfirmationMailGenerator implements MailGenerator {
private BasicUser user;
private String htmlTemplate = "HTMLConfirmationMailTemplate.vsl";
private String plainTemplate = "PlainConfirmationMailTemplate.vsl";
public ConfirmationMailGenerator(BasicUser user) {
this.user = user;
}
public StringWriter generateHTML() throws Exception {
Properties props = new Properties();
props.setProperty("resource.loader", "wepapp");
props.setProperty("webapp.resource.loader.class", "org.apache.velocity.tools.view.WebappResourceLoader");
props.setProperty("webapp.resource.loader.path", "/WEB-INF/mailtemplates/");
VelocityEngine engine = new VelocityEngine(props);
VelocityContext context = new VelocityContext();
engine.init();
Map map = createDataModel();
context.put("user", map);
Template template = engine.getTemplate(htmlTemplate);
StringWriter writer = new StringWriter();
template.merge(context, writer);
return writer;
}
...
}
The files is of course saved in /WEB-INF/mailtemplates/.
If I use this I get this error:
SEVERE: ResourceManager : unable to find resource 'HTMLConfirmationMailTemplate.vsl' in any resource loader.
SEVERE: The log message is null.
Thank you for your time:)
You are using the Webapp resourceloader, which is intended for pages served by the Velocity Tools servlet. (It requires some special initialization to find the root of the servlet context).
I recommend you use the ClasspathResourceLoader, then put the files into WEB-INF/classes, or elsewhere in your classpath. This is really the most straight forward approach.
resource.loader = class
class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
More info is here:
https://velocity.apache.org/engine/1.7/apidocs/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.html
Will Glass answer is correct, but the configuration should be:
resource.loader = class
class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
Note the class at the beginning of the second line. See the links provided by him for more details!.
Note: Making an answer instead of a comment due to privileges.
Velocity is probably using the class loader to find those files. I'd recommend putting them in WEB-INF/classes, which is in the CLASSPATH by default.
I am fine it as follow,
In velocity.properties file
resource.loader=class, file
class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
file.resource.loader.class=org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path=vm_template
runtime.log.logsystem.class=org.apache.velocity.runtime.log.SimpleLog4JLogSystem
runtime.log.logsystem.log4j.category=velocity
input.encoding=UTF-8
output.encoding=UTF-8
And at my java class
import java.io.StringWriter;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.tools.generic.DateTool;
import org.apache.velocity.tools.generic.EscapeTool;
import org.apache.velocity.tools.generic.LoopTool;
import org.apache.velocity.tools.generic.MathTool;
import org.apache.velocity.tools.generic.NumberTool;
import org.apache.velocity.tools.generic.SortTool;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class VelocitySupport implements InitializingBean {
private static Logger log = Logger.getLogger(VelocitySupport.class);
#Autowired private Properties properties;
public final void afterPropertiesSet() throws Exception {
location = location.replace("classpath:", "");
Resource res = new ClassPathResource(location);
Properties prop = new Properties();
prop.load(res.getInputStream());
String staticDir = System.getProperty("staticDir");
String tempPath = prop.getProperty("file.resource.loader.path");
tempPath = staticDir + "/" + tempPath;
prop.setProperty("file.resource.loader.path", tempPath);
Velocity.init(prop);
}
public static String merge(final String template, final VelocityContext vc) throws Exception {
try {
vc.put("date", new DateTool());
vc.put("escape", new EscapeTool());
vc.put("math", new MathTool());
vc.put("number", new NumberTool());
vc.put("iterate", new LoopTool());
vc.put("sort", new SortTool());
Template temp = Velocity.getTemplate(template);
StringWriter sw = new StringWriter();
temp.merge(vc, sw);
sw.flush();
return sw.toString();
}
catch (ResourceNotFoundException e) {
log.error("", e);
throw e;
}
catch (ParseErrorException e) {
log.error("", e);
throw e;
}
}
private String location;
public final void setLocation(final String location) {
this.location = location;
}
}
And insert VM arguments of project as follow..
-DstaticDir= "your directory for template path"
That may be helpful for you...
For resolving this error
--WEB-INF/classes and all the JARs in WEB-INF/lib are in the CLASSPATH. Try moving your folder with the .vm files under WEB-INF/classes
--dont put the abolute path eg. if abc.vm file is in /public_html/WEB-INF folder then put path = "/public_html/WEB-INF/abc.vm" for velocity template path.