a simple question but i litterally can not remember, basically i want to run java methods in an certain order, i did have it working perfectly, but i have had to add something to the start and now it will not run in order
Basically before was this code,
#PostConstruct
public void init() {
//System.out.println(destinationPDF);
//System.out.println(destination);
// Get the username from the login page, this is used to create a folder for each user
System.out.println("called get username");
username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
}
public void File() {
File theFile = new File(destination + username); // will create a sub folder for each user (currently does not work, below hopefully is a solution)
theFile.mkdirs();
System.out.println("Completed File");
}
it would run and automatically call the next required method, it would call them in this order :
INFO: buttonToUploadText invoked
INFO: called get username
INFO: called handle file
INFO: Completed Creation of folder
INFO: Now in copying of file proccess
INFO: Completed Creation of folder for copy of PDF
INFO: End of copying file creation
INFO: Called CopyFile
INFO: New file created!
INFO: Copying is now happening
But i have added a new method, that calls variables from a file :
#PostConstruct
public void loadProp() {
System.out.println("Loading properties");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("config.properties"); //points to a properties file, this will load up destinations instead of having to declare them here
try {
configProp.load(in);
System.out.println(configProp.getProperty("destinationPDF"));
System.out.println(configProp.getProperty("destination"));
System.out.println(configProp.getProperty("fileList"));
} catch (IOException e) {
e.printStackTrace();
}
}
This now must run first when it is triggered in order to declare variables, however now it will now run public void int() once complete instead it skips a lot and runs public void handleFileUpload
so what is the best way of calling public void init() from public void loadProp() {
Edit 2:
private Properties configProp = new Properties();
public void loadProp() {
System.out.println("Loading properties");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("config.properties"); //points to a properties file, this will load up destinations instead of having to declare them here
try {
configProp.load(in);
System.out.println(configProp.getProperty("destinationPDF"));
System.out.println(configProp.getProperty("destination"));
System.out.println(configProp.getProperty("fileList"));
} catch (IOException e) {
e.printStackTrace();
}
}
private String destinationPDF = configProp.getProperty("destinationPDF");
public String destination = configProp.getProperty("destination");
private String username;
//public static String destination = "D:/Documents/NetBeansProjects/printing~subversion/fileupload/uploaded/"; // main location for uploads//TORNADO ONLY //"D:/My Documents/NetBeansProjects/printing~subversion/fileupload/uploaded/"; // USE ON PREDATOR ONLY
public static String NewDestination;
public static String UploadedfileName;
public static String CompletefileName;
//
//Strings for file copy
//
//private String destinationPDF = "D:/Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/pdf/"; //USE ON TORNADO//"D:/My Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/pdf/";//USE ON PREDATOR
private String NewdestinationPDF;
public static String PdfLocationViewable;
//
#PostConstruct
public void init() {
FileUploadController.loadProp();
//System.out.println(destinationPDF);
//System.out.println(destination);
// Get the username from the login page, this is used to create a folder for each user
System.out.println("called get username");
username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
}
You can and should have only one #PostConstruct method.
Replace
#PostConstruct
public void loadProp() {
// ...
}
#PostConstruct
public void init() {
// ...
}
By
#PostConstruct
public void postConstruct() {
loadProp();
init();
}
private void loadProp() {
// ...
}
private void init() {
// ...
}
(I'd only consider renaming postConstruct() to init() and rename the original init() to something else matching its actual job)
Related
I have ran this code and the screenshot gets captured after the chrome browser closes (#After)
If i comment out CloseBrowser(); the screenshot gets captured but the chromebrowser stay open.
I want the screenshot to capture on a failed test then close the browser.
in summary
The screenshot currently captures after the browser closes, which is just a blank .png
I want the screenshot to capture when a test fails just before the browser closes
Thanks
public class TestClass extends classHelper//has BrowserSetup(); and CloseBrowser(); {
#Rule
public ScreenshotTestRule my = new ScreenshotTestRule();
#Before
public void BeforeTest()
{
BrowserSetup();// launches chromedriver browser
}
#Test
public void ViewAssetPage()
{
//My test code here//And want to take screenshot on failure
}
#After
public void AfterTest() throws InterruptedException
{
CloseBrowser();//closes the browser after test passes or fails
}
}
class ScreenshotTestRule implements MethodRule {
public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object o) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
try {
statement.evaluate();
} catch (Throwable t) {
captureScreenshot(frameworkMethod.getName());
throw t; // rethrow to allow the failure to be reported to JUnit
}
}
public void captureScreenshot(String fileName) {
try {
new File("target/surefire-reports/").mkdirs(); // Insure directory is there
FileOutputStream out = new FileOutputStream("target/surefire-reports/screenshot-" + fileName + ".png");
out.write(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES));
out.close();
} catch (Exception e) {
// No need to crash the tests if the screenshot fails
}
}
};
}
}
You can implement TestNG Listeners to execute code before a test or after a test
Or when a test fails or succeeded etc.
Implement it like below and put your screenshot in the method i showed
public class Listeners implements ITestListener {
Methods…
And put the screenshot code inside the method below:
#Override
public void onTestFailure(ITestResult result) {
code for screenshot
}
}
So i have found a way to implement the screenshots. I have created a method that will take a screenshot. I have put a try and catch around my test code and catch an exception and calling the method to take a screenshot.
public class TestClass extends classHelper//has BrowserSetup(); and CloseBrowser(); {`
#Rule
public ScreenshotTestRule my = new ScreenshotTestRule();
#Before
public void BeforeTest()
{
BrowserSetup();// launches chromedriver browser
}
#Test
public void ViewAssetPage()
{
try
{
//My test code here//And want to take screenshot on failure
}
catch(Exception e)
{
//print e
takeScreenShot();
}
}
#After
public void AfterTest() throws InterruptedException
{
CloseBrowser();//closes the browser after test passes or fails
}
}
///////////////////////////////////////////
void takeScreenShot()
{
try
{
int num = 0;
String fileName = "SS"+NAME.getMethodName()+".png";//name of file/s you wish to create
String dir = "src/test/screenshot";//directory where screenshots live
new File(dir).mkdirs();//makes new directory if does not exist
File myFile = new File(dir,fileName);//creates file in a directory n specified name
while (myFile.exists())//if file name exists increment name with +1
{
fileName = "SS"+NAME.getMethodName()+(num++)+".png";
myFile = new File(dir,fileName);
}
FileOutputStream out = new FileOutputStream(myFile);//creates an output for the created file
out.write(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES));//Takes screenshot and writes the screenshot data to the created file
//FileOutputStream out = new FileOutputStream("target/surefire-reports/" + fileName);
out.close();//closes the outputstream for the file
}
catch (Exception e)
{
// No need to crash the tests if the screenshot fails
}
This might help:
https://github.com/junit-team/junit4/issues/383
The ordering for rule execution has changed with new 'TestRule'
When I build project by maven, it's OK, but when deploy it by Tomkat, I have NullPointerException.
Class, where can be problem - PropertiesManager.
logline: PropertiesManager.getApplicationProperties(PropertiesManager.java:31)
public class PropertiesManager {
private static final String PROPERTY_FILE_NAME =
"resources/application.properties";
private static PropertiesManager Instance;
private Properties properties;
private PropertiesManager() {
}
public static PropertiesManager getInstance() {
if (Instance == null) {
Instance = new PropertiesManager();
}
return Instance;
}
public Properties getApplicationProperties() {
if (properties == null) {
properties = new Properties();
try (InputStream stream = Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream(PROPERTY_FILE_NAME)) {
properties.load(stream);
} catch (IOException e) {
throw new ApplicationException("Failed to load property file", e);
}
}
return properties;
}
}
And logline: ApplicationLifecycleListener.contextInitialized(ApplicationLifecycleListener.java:14)
Class ApplicationLifecycleListener:
public class ApplicationLifecycleListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
Properties applicationProperties = PropertiesManager.getInstance().getApplicationProperties();
DBManager.getInstance().initialize(applicationProperties);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
DBManager.getInstance().stopDb();
}
}
What is problem can be?
Without providing the file with the exact line you see the NullPointerException (none of the files you provided have the lines shown in log), it is difficult to be sure. But one hint is that although you put your resources files to be built with Maven in the '<project>/src/main/resources' folder, when built and packing the war file, it will put your application resource files in the 'WEB-INF/classes' folder which is part of the application default classpath. Therefore, to correctly reference them using the method Thread.currentThread().getContextClassLoader().getResourceAsStream(...) you should not add the 'resources\...' prefix to the file name, since this method already look files in the default application classpath. Remove the prefix and see if it works. Please, refer to this answer for more detail.
What is the best way of writing a unit test for a method, such as my setProperties (see below), that uses a private configuration variable (config). I tried but failed to override it using reflection and Makito, but without success. I realize that changing the design to make the code easier to test is best, but I want to created some unit tests before I refactor the code.
public class MainClass {
private final java.lang.String config = "app.properties";
public TestClass() {
try {
setProperties();
} catch (Exception e) {
e.printStackTrace();
}
}
public void setProperties() throws Exception {
try {
InputStream input = new BufferedInputStream(new FileInputStream(config));
..
..
} catch (Exception exception) {
throw exception;
}
}
}
Do refactor a tiny bit by extracting a method with a parameter that takes an input stream. Call this new method (probably package-protected) from the old one. Write tests against the new method. Then do more refactorings.
This is an indication of a broken design; don't hard-code things like this. Better yet, determine what the appropriate responsibility for this class is, and, in decreasing order of preference:
pass in an object with the configuration properties, strongly typed
pass in a Map with the configuration properties
pass in an InputStream for the properties file
As File objects are never available from a jar, you shouldn't ever make interfaces like this more specific than InputStream or Reader, so that you can always pass in streams from your jar classpath.
So you can use Properties class in Java for this. Please have a look at this code.
public class PropertyUtil {
private static Properties prop;
private static Logger logger = Logger.getLogger(PropertyUtil.class);
private PropertyUtil() {
}
public void setProperty() {
String filePath = System.getenv("JAVA_HOME") + "/lib" + "/my_file.properties";
prop = new Properties();
try (InputStream input = new FileInputStream(filePath)) {
prop.load(input);
} catch (IOException ex) {
logger.error("Error while reading property file " + ex);
}
}
public static String getProperty(String key) {
if (prop.containsKey(key)) {
return prop.getProperty(key);
} else {
return null;
}
}
public static <T> T getProperty(String key, Class<T> claz) {
if (claz.getName().equals(Integer.class.getName())) {
return claz.cast(Integer.parseInt(prop.getProperty(key)));
}
if (claz.getName().equals(Long.class.getName())) {
return claz.cast(Long.parseLong(prop.getProperty(key)));
}
if (claz.getName().equals(Boolean.class.getName())) {
return claz.cast(Boolean.parseBoolean(prop.getProperty(key)));
}
if (claz.getName().equals(Double.class.getName())) {
return claz.cast(Double.parseDouble(prop.getProperty(key)));
}
if (claz.getName().equals(String.class.getName())) {
return claz.cast(prop.getProperty(key));
}
return null;
}
I implemented two customized handler to log information on DB and an additional flat file (DBHandler and MyFileHandler). This new log handlers will be used by a single class on a specific package.
I attached the two new loggers to a specific package only.
The idea is to switch between this two handlers (file and database)for the classes contaiend on a specific package, but currently with the current configuration I could not do that, so either I am logging with both handler either there is no log at all.
I tried to set the log level for DB handler to off but it is still logging normally on DB.
below the configuration file is use logging.properties
############################################################
##### Global properties
############################################################
handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler, com.test.logging.DBHandler, com.test.logging.MyFileHandler
.level = INFO
############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################
java.util.logging.FileHandler.level = ALL
java.util.logging.FileHandler.pattern = %t/CLog%g.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
com.test.logging.MyFileHandler.level = ALL
com.test.logging.MyFileHandler.pattern = %t/custLog%g.log
com.test.logging.MyFileHandler.limit = 50000
com.test.logging.MyFileHandler.count = 1
com.test.logging.MyFileHandler.formatter = java.util.logging.SimpleFormatter
com.test.logging.DBHandler.level=OFF
com.test.ccb.mon.handlers=com.test.logging.DBHandler, com.test.logging.MyFileHandler
The class using the logger to track he inforamtion is below
package com.test.ccb.mon;
public class Utils {
public static final Logger logger = Logger.getLogger(Utils.class.getCanonicalName());
public void logging()
{
//processing
logger.info("message);
}
}
DBHandler class:
public class DBHandler extends Handler {
#Override
public void close() throws SecurityException {
}
#Override
public void flush() {
}
#Override
public void publish(LogRecord logRecord) {
if (isLoggable(logRecord))
{
try {
//SQL call to insert onDB
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
MyFileHandler class:
public class MyFileHandler extends FileHandler{
public MyileHandler() throws IOException, SecurityException {
super();
}
#Override
public void close() throws SecurityException {
super.close();
}
#Override
public void flush() {
super.flush();
}
#Override
public void publish(LogRecord record) {
super.publish(record);
}
}
The Handler class doesn't read any properties from the LogManager by default. You have to code that logic in all of your subclasses.
public class DBHandler extends Handler {
public DBHandler() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".level");
try {
if (v != null) {
super.setLevel(Level.parse(v));
}
} catch (RuntimeException re) {
reportError(v, re, ErrorManager.OPEN_FAILURE);
}
//#todo create code to parse filter, formatter, encoding, etc.
}
#Override
public void close() throws SecurityException {
}
#Override
public void flush() {
}
#Override
public void publish(LogRecord logRecord) {
if (isLoggable(logRecord)) {
try {
//SQL call to insert onDB
} catch (Exception e) {
reportError("", e, ErrorManager.WRITE_FAILURE);
}
}
}
}
Reproducing your problem is not so easy for me. With handler classes similar to yours, changes to the configuration file have the expected effect. With the DBHandler.level=OFF setting, the database handler output is missing for me:
Aug 11, 2015 1:47:26 PM com.test.ccb.mon.Utils logging
DBHandler.publish - handler level: OFF; log record level: INFO
INFO: message
MyFileHandler - message
Logging handlers:
###java.util.logging.FileHandler-ALL
###java.util.logging.ConsoleHandler-ALL
###com.test.logging.DBHandler-OFF
###com.test.logging.MyFileHandler-ALL
Your debug code to print the logging handlers is now also included in the following main method to your Utils class. You could run this method yourself, to see whether this way of reading the configuration file works better for you:
public static void main(final String[] arguments) throws IOException
{
final String fileName = "logging.properties";
final InputStream propertiesStream = Utils.class.getResourceAsStream(fileName);
//final InputStream propertiesStream = new FileInputStream("path to file");
LogManager.getLogManager().readConfiguration(propertiesStream);
new Utils().logging();
System.out.println();
// No handlers for this logger directly, but four for its parent.
System.out.println("Logging handlers:");
for (final Handler handler : logger.getParent().getHandlers())
System.out.println("###" + handler.getClass().getName()
+ "-" + handler.getLevel());
}
A very simple version of your DBHandler class could look like this (please note the if (isLoggable(record)) check in the publish method):
package com.test.logging;
import java.util.logging.*;
/**
* Logging handler that stores logging in the database.
*/
public class DBHandler extends Handler {
#Override
public void publish(final LogRecord record) {
System.out.println("DBHandler.publish - handler level: " + getLevel()
+ "; log record level: " + record.getLevel());
if (isLoggable(record))
System.out.println(getClass().getSimpleName() + " - " + record.getMessage());
}
#Override
public void flush() {
// Empty.
}
#Override
public void close() throws SecurityException {
// Empty.
}
}
I try make implementation for comparing the files before they are uploaded.
If file whith name is exist in system ask about create new version or just override it.
Here is the problem, how to get file name?
I can't use receiveUpload(), because after this method file is remove from upload component ?
The problem is that once you start an upload using the Upload component, it can only be interrupted by calling the interruptUpload() method, and you cannot resume anytime later.
The interruption is permanent.
This means you cannot pause in the middle of the upload to see if you already have the file in your system. You have to upload the file all the way.
Considering this drawback, you can sill check in your system if you have the file, after the upload finishes. If you have the file, you can show a confirmation dialog in which you decide wether to keep the file or overwrite.
The following is an example in which I check in the "system" (I just keep a String list with the filenames) if the file has already been uploaded:
public class RestrictingUpload extends Upload implements Upload.SucceededListener, Upload.Receiver {
private List<String> uploadedFilenames;
private ByteArrayOutputStream latestUploadedOutputStream;
public RestrictingUpload() {
setCaption("Upload");
setButtonCaption("Upload file");
addSucceededListener(this);
setReceiver(this);
uploadedFilenames = new ArrayList<String>();
}
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
latestUploadedOutputStream = new ByteArrayOutputStream();
return latestUploadedOutputStream;
}
#Override
public void uploadSucceeded(SucceededEvent event) {
if (fileExistsInSystem(event.getFilename())) {
confirmOverwrite(event.getFilename());
} else {
uploadedFilenames.add(event.getFilename());
}
}
private void confirmOverwrite(final String filename) {
ConfirmDialog confirmDialog = new ConfirmDialog();
String message = String.format("The file %s already exists in the system. Overwrite?", filename);
confirmDialog.show(getUI(), "Overwrite?", message, "Overwrite", "Cancel", new ConfirmDialog.Listener() {
#Override
public void onClose(ConfirmDialog dialog) {
if (dialog.isConfirmed()) {
copyFileToSystem(filename);
}
}
});
}
private void copyFileToSystem(String filename) {
try {
IOUtils.write(latestUploadedOutputStream.toByteArray(), new FileOutputStream(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
}
}
private boolean fileExistsInSystem(String filename) {
return uploadedFilenames.contains(filename);
}
}
Note that I have used 2 external libraries:
Apache Commons IO 2.4 (http://mvnrepository.com/artifact/commons-io/commons-io/2.4) for writing to streams
ConfirmDialog from Vaadin Directory (https://vaadin.com/directory#addon/confirmdialog)
You can get the code snippet for this class from Gist: https://gist.github.com/gabrielruiu/9960772 which you can paste into your UI and test it out.