I have been asked to write a program that will read a file as it is updated (4 times/millisecond) and print the number of lines to the system. To do this, I have the following code:
package threadFile;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
public class ReadFile
{
private String path;
public ReadFile(String file_name)
{
path = file_name;
}
public String[] OpenFile() throws IOException
{
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
int numberOfLines = readLines();
String[]textData = new String[numberOfLines];
int i;
for(i=0; i< numberOfLines; i++)
{
textData[i] = textReader.readLine();
}
textReader.close();
return textData;
}
#SuppressWarnings("unused")
int readLines() throws IOException
{
FileReader file_to_read = new FileReader(path);
BufferedReader bf = new BufferedReader(file_to_read);
String aLine;
int numberOfLines = 0;
while ((aLine = bf.readLine()) != null)
{
numberOfLines++;
}
bf.close();
return numberOfLines;
}
The above code is meant to open a text file and read the number of lines there are. My issue is, getting the program to update as the file is written to (by another section of the program).The below code is a thread, and is meant to call into ReadFile for instructions.
I need the program to constantly read the contents, and accurately update the line count as it is edited.
If I understand correctly your requirement you want to use one file for Inter Process Communication (or inter thread-communication to be more exact for your case). If this is the case you probably want to use the file as MemoryMapped file.
A simple description of MemoryMapped file usage is done here.
As it was already said, Java 1.7 Watch Service is also a solution that could work.
Solution
The solution to my problem was a little more involved than expected.
Reading Files
package threadFile;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class PrintReader implements Runnable
{
#SuppressWarnings("unused")
private final String taskName;
final String file_name = "C:/Users/wigginsm/Desktop/Log.txt";
public PrintReader(String name)
{
taskName = name;
}
public void run()
{
boolean loop = true;
while(loop = true)
try
{
FileReader fr = new FileReader(file_name);
BufferedReader br = new BufferedReader(fr);
String line = br.readLine();
int count = 0;
while(line!=null)
{
count++;
line=br.readLine();
}
FileInputStream fileIn = new FileInputStream(file_name);
BufferedReader fileR = new BufferedReader(new InputStreamReader(fileIn));
String strLine = null, tmp;
while((tmp = fileR.readLine())!=null)
{
strLine = tmp;
}
String lastLine = strLine;
System.out.println("Last entered line: " + lastLine + "\n" + "Total number of Lines: " + count);
br.close();
fileR.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
The above class is responsible for reading the file, declared with "file_name".
Writing to Files
package threadFile;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;
public class WriteToFile implements Runnable
{
#SuppressWarnings("unused")
private final String taskName;
class WriteFile
{
private String path;
private boolean append_to_file = false;
public WriteFile(String file_path, boolean append_value)
{
path = file_path;
append_to_file = append_value;
}
public void writeToFile(String timestamp) throws IOException
{
int i = 0;
while(i<1)
{
FileWriter write = new FileWriter(path, append_to_file);
Calendar current = Calendar.getInstance();
int ms = current.get(Calendar.MILLISECOND);
int minute = current.get(Calendar.MINUTE);
int second = current.get(Calendar.SECOND);
int hour = current.get(Calendar.HOUR_OF_DAY);
int day = current.get(Calendar.DAY_OF_YEAR);
int month = current.get(Calendar.MONTH)+1;
int year = current.get(Calendar.YEAR);
timestamp = day + "/" + month + "/" + year + " " + hour + ":" + minute + ":" + second + ":" + ms;
PrintWriter print_line = new PrintWriter(write);
try
{
Thread.sleep(250);
}
catch(InterruptedException e)
{
Thread.currentThread().interrupt();
}
print_line.printf("%s" + "%n", timestamp);
print_line.close();
}
}
}
//constructor
public WriteToFile(String name)
{
taskName = name;
}
#SuppressWarnings("unused")
public synchronized void run()
{
boolean loop = true;
while(loop = true)
{
try
{
String file_name = "C:/Users/wigginsm/Desktop/Log.txt";
Calendar current = Calendar.getInstance();
int ms = current.get(Calendar.MILLISECOND);
int minute = current.get(Calendar.MINUTE);
int second = current.get(Calendar.SECOND);
int hour = current.get(Calendar.HOUR_OF_DAY);
int day = current.get(Calendar.DAY_OF_YEAR);
int month = current.get(Calendar.MONTH)+1;
int year = current.get(Calendar.YEAR);
String timestamp = day + "/" + month + "/" + year + " " + hour + ":" + minute + ":" + second + ":" + ms;
WriteFile data = new WriteFile(file_name, true);
data.writeToFile(timestamp);
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
}
}
The above code is responsible for writing to the file. The only reason for the while loop to continue indefinitely is due to my program specification. This can easily be altered to fit any iteration.
Execution
package threadFile;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
public class execute
{
public static void main(String[] args)
{
final String file_name = "C:/Users/wigginsm/Desktop/Log.txt";
WriteToFile writes = new WriteToFile(file_name);
PrintReader reads = new PrintReader(file_name);
ExecutorService thread = Executors.newCachedThreadPool();
thread.execute(reads);
thread.execute(writes);
thread.shutdown();
}
}
This is the main class, it is responsible for handling the threading. Both PrintWrite and WriteToFile have the "synchronize" statement, as run() in both classes accesses the file.
Related
I made a simple java program that lets you create a stocks scanner/screener. There aren't many features yet, but there is a problem with existing features. I have a class that has a method that creates an array of all stock tickers and returns it. Here it is:
package classes;
import Utility.ArrayModification;
import variables.Ticker;
import java.io.*;
import java.util.Scanner;
public class Market {
public static Ticker[] getAllTickers() throws FileNotFoundException {
Ticker[] allTickers = {};
File currentDirectory = new File(new File("").getAbsolutePath());
String allTickersDirectory = currentDirectory + "\\src\\AllTickers.txt";
Scanner scanner = new Scanner(new File(allTickersDirectory));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if(!(line.contains("^"))) {
allTickers = ArrayModification.appendTicker(allTickers, new Ticker(line));
}
}
return allTickers;
}
}
AllTickers.txt is a text file with the names of all tickers in it. I also have another class that stores a datatype, Ticker. Here it is:
package variables;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class Ticker {
private String savedSymbol;
public Ticker(String symbol) {
savedSymbol = symbol;
}
public String getTicker() {
return savedSymbol;
}
public Ticker setTicker(String symbol) {
savedSymbol = symbol;
return this;
}
public double getPrice() throws IOException {
try {
String stringURL = "https://markets.businessinsider.com/stocks/" + savedSymbol + "-stock";
URL url = new URL(stringURL);
URLConnection urlConn = url.openConnection();
InputStreamReader inStream = new InputStreamReader(urlConn.getInputStream());
BufferedReader buff = new BufferedReader(inStream);
String stringPrice = "-1";
String line = buff.readLine();
while (line != null) {
if (line.contains("price: ")) {
int target = line.indexOf("price: ");
int deci = line.indexOf(".", target);
int start = deci;
int stop = deci;
while (line.charAt(start) != ' ') {
start--;
}
while (line.charAt(stop) != ',') {
stop++;
}
stringPrice = line.substring(start + 1, stop);
break;
}
line = buff.readLine();
}
double price = Double.parseDouble(stringPrice);
return price;
}
catch(Exception e) {
return -1;
}
}
public double getMarketCap() throws IOException {
try {
String stringURL = "https://finviz.com/quote.ashx?t=" + savedSymbol;
URL url = new URL(stringURL);
URLConnection urlConn = url.openConnection();
InputStreamReader inStream = new InputStreamReader(urlConn.getInputStream());
BufferedReader buff = new BufferedReader(inStream);
String stringMarketCap = "-1";
double finalMarketCap = -1;
String line = buff.readLine();
while (line != null) {
if (line.contains(">Market Cap<")) {
int deci = line.indexOf(".");
int start = deci;
int stop = deci;
while (line.charAt(start) != '>') {
start--;
}
while (line.charAt(stop) != '<') {
stop++;
}
stringMarketCap = line.substring(start + 1, stop - 1);
double marketCap = Double.parseDouble(stringMarketCap);
if (line.charAt(stop - 1) == 'B') {
finalMarketCap = marketCap * 1000000000;
} else if (line.charAt(stop - 1) == 'M') {
finalMarketCap = marketCap * 1000000;
}
break;
}
line = buff.readLine();
}
return finalMarketCap;
}
catch(Exception e) {
return -1;
}
}
}
Using all of these, you can create a simple scanner that scans for stocks with a price of, for example, 0 - 15. You can do this by doing this:
import classes.Market;
import variables.Ticker;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
Ticker[] allTickers = Market.getAllTickers();
for(int i = 0; i< allTickers.length; i++){
Ticker ticker = allTickers[i];
if(ticker.getPrice() > 0 && ticker.getPrice() < 15) {
System.out.println(ticker.getTicker());
}
}
}
}
It prints out all of the qualifying stocks. However, it is EXTREMELY slow. So slow that it's basically unusable. It is this way because the ticker.getPrice() method has to connect to markets.businessinsider.com, extract the HTML code, find the correct index, and get the price for every single stock out of the 6000 in AllTIckers.txt. Would there be a way to do this faster?
Newbie here. My goal is to read a txt file, eliminate characters ("-" and " "), and replace the existing text with the new cleaned up text.
example: 855-555-1234 >> 8555551234.
I'm stuck on my append boolean. I'm using the guides here and here.
When my append is true then I get the text that I want at the end of the file, but when it is false, the file is completely blank.
My main method looks like:
public class Main {
public static void main(String[] args) throws IOException{
String file_name = "C:/TollFreeToPort.txt";
try {
ReadFile file = new ReadFile(file_name);
String[] aryLines = file.OpenFile();
WriteFile data = new WriteFile(file_name, true);
int i;
for (i = 0; i < aryLines.length; i++) {
System.out.println(aryLines[i]);
data.writeToFile(aryLines[i]);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
My ReadFile Class:
package textfiles;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
public class ReadFile {
private String path;
public ReadFile(String file_path) {
path = file_path;
}
public String[] OpenFile() throws IOException {
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
int i;
for (i = 0; i < numberOfLines; i++) {
textData[i] = textReader.readLine()
.replace("-", "")
.replace(" ", "");
}
textReader.close();
return textData;
}
int readLines() throws IOException {
FileReader file_to_read = new FileReader(path);
BufferedReader bf = new BufferedReader(file_to_read);
String aLine;
int numberOfLines = 0;
while ((aLine = bf.readLine()) != null) {
numberOfLines++;
}
bf.close();
return numberOfLines;
}
}
My WriteFile Class:
package textfiles;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.IOException;
public class WriteFile {
private String path;
private boolean append_to_file = false;
public WriteFile(String file_path) {
path = file_path;
}
public WriteFile(String file_path, boolean append_value) {
path = file_path;
append_to_file = append_value;
}
public void writeToFile (String textLine) throws IOException{
FileWriter write = new FileWriter(path, append_to_file);
PrintWriter print_line = new PrintWriter(write);
print_line.printf("%s" + "%n", textLine);
print_line.close();
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm programming a multiple file downloader in Java with JavaFx, but i have some problems with threading.
The problem i have is with the threading part.
I want to start multiple downloads (different urls / files) at the same time, for example two. If i start this two downloadthreads (I think) a race condition happens, because the filename and filesize for both threads are the same and there is also only one file on the HDD, not two as expected.
I am sure it's a race condition problem, but how can i solve it?
Main.java
package de.minimal.program;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import de.minimal.program.model.Download;
import de.minimal.program.util.Dl;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
public class Main extends Application {
private ObservableList<Download> downloadData = FXCollections.observableArrayList();
private int i = 0;
public ObservableList<Download> getDownloadData(){
return downloadData;
}
#Override
public void start(Stage primaryStage) {
downloadData.add(new Download("http://mirror.de.leaseweb.net/videolan/vlc/2.2.1/win32/vlc-2.2.1-win32.exe"));
downloadData.add(new Download("http://releases.ubuntu.com/15.10/ubuntu-15.10-desktop-amd64.iso"));
ArrayList<Thread> t = new ArrayList<Thread>();
ExecutorService executor = Executors.newFixedThreadPool(2, new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread a = new Thread(r);
a.setName("Thread " + i);
i++;
t.add(a);
return a;
}
});
for(Download dl : downloadData){
Dl d = new Dl(dl);
executor.execute(d);
}
}
public static void main(String[] args) {
launch(args);
}
}
DL.java
package de.minimal.program.util;
import java.util.List;
import de.minimal.program.httpconnection.HttpConnection;
import de.minimal.program.model.Download;
import javafx.concurrent.Task;
public class Dl extends Task<List<Download>> implements Runnable{
private Download download;
private HttpConnection connection;
public Dl(Download download){
this.download = download;
}
#Override
protected synchronized List<Download> call() throws Exception {
connection = new HttpConnection(download);
connection.downloadFile();
return null;
}
}
HTTPConnection.java
package de.minimal.program.httpconnection;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import de.minimal.program.model.Download;
public class HttpConnection {
private static String url;
private Download download;
private static final int BUFFER_SIZE = 4096;
public HttpConnection(Download download){
this.download = download;
}
public void downloadFile() throws IOException{
String saveDir = download.getDownloadSavePath();
url = download.getDownloadUrl();
URL obj = new URL(url);
HttpURLConnection connection = (HttpURLConnection) obj.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
// Forbid redirects for file resuming reasons
connection.setInstanceFollowRedirects(false);
int responseCode = connection.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_PARTIAL) {
String fileName = "";
String disposition = connection.getHeaderField("Content-Disposition");
long contentLength = connection.getContentLengthLong();
boolean appendToFile = false;
if(responseCode == HttpURLConnection.HTTP_PARTIAL)
appendToFile = true;
if(download.getFilesize() == 0){
download.setFilesize(contentLength);
}
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
}
} else {
// extracts file name from URL
fileName = url.substring(url.lastIndexOf("/") + 1, url.length());
}
download.setFilename(fileName);
// opens input stream from the HTTP connection
InputStream inputStream = connection.getInputStream();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveFilePath, appendToFile);
int bytesRead = -1;
long downloadedBytes = download.getTransferedBytes();
long start = System.currentTimeMillis();
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
downloadedBytes += bytesRead;
if(System.currentTimeMillis() - start >= 2000){
download.setTransferedBytes(downloadedBytes);
start = System.currentTimeMillis();
}
}
outputStream.close();
inputStream.close();
System.out.println("Thread " + Thread.currentThread().getName() + " Filedownload " + fileName + " finished");
} else {
System.out.println("No file to download. Server replied HTTP code: " + responseCode);
}
connection.disconnect();
}
}
Download.java
package de.minimal.program.model;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Download {
private final StringProperty filename;
private final StringProperty filepath;
private final LongProperty filesize;
private final LongProperty transferedBytes;
private String downloadUrl;
private String downloadSavePath = "SET PATH ";
public Download(){
this("");
}
public Download(String downloadUrl){
this.downloadUrl = downloadUrl;
this.filename = new SimpleStringProperty(downloadUrl);
this.filepath = new SimpleStringProperty(downloadSavePath);
this.filesize = new SimpleLongProperty(0);
this.transferedBytes = new SimpleLongProperty(0);
}
// Filename
public synchronized String getFilename(){
return filename.get();
}
public synchronized void setFilename(String filename){
System.out.println("Thread " + Thread.currentThread().getName() + " Set filename: " + filename);
this.filename.set(filename);
}
public synchronized StringProperty filenameProperty(){
return filename;
}
// Filepath
public String getFilepath(){
return filepath.get();
}
public void setFilepath(String filepath){
System.out.println("Set filepath: " + filepath);
this.filepath.set(filepath);
}
public StringProperty filepathProperty(){
return filepath;
}
// Filesize
public Long getFilesize(){
return filesize.get();
}
public void setFilesize(Long filesize){
System.out.println("Thread " + Thread.currentThread().getName() + " Set filesize: " + filesize);
this.filesize.set(filesize);
}
public LongProperty filesizeProperty(){
return filesize;
}
// TransferedBytes
public Long getTransferedBytes(){
return transferedBytes.get();
}
public void setTransferedBytes(Long transferedBytes){
System.out.println("Thread " + Thread.currentThread().getName() + " bytes transfered " + transferedBytes);
this.transferedBytes.set(transferedBytes);
}
public LongProperty transferedBytesProperty(){
return transferedBytes;
}
// URL
public String getDownloadUrl(){
return downloadUrl;
}
public void setDownloadUrl(String downloadUrl){
this.downloadUrl = downloadUrl;
}
// SavePath
public String getDownloadSavePath(){
return downloadSavePath;
}
public void setDownloadSavePath(String downloadSavePath){
this.downloadSavePath = downloadSavePath;
}
}
EDIT:
This is the minimal code.
You can add links, start and stop downloads, and change the number of simultaneous concurrent downloads.
EDIT 2:
Minified it again. Hope this time its better.
Adds two downloadlinks and starts them immediately. Reproduces the mentioned problem.
EDIT 3:
Solved it.
The problem was the
private static String url;
I remember that my professor told once that static variables are not thread safe. So more information can found here
10 points about Static in Java point 2
Is writing in a single file a real constraint ? What you could do is to write in separate files, then once the files are complete, merge them into a single one.
Alternatively, if the results from the requests are not so big and could fit in memory, you could directly return the files from the downloading threads, and then write them into a single file.
So I have a directory in my local C drive.
C:/Search Files/Folder [number]/hello.txt
Inside Search Files I have four foldes named:
Folder 1
Folder 2
Folder 3
Folder 4
Inside Folder 1 I have a a file called hello.txt with some String in it.
What I want to do is grab the fileDirectory, fileName and fileContent and put it in a List of XMLMessage objects. I have pasted my main class and my XMLMessage POJO. When I run it, I am getting an indexOutOfBoundsException. I have been stuck for a couple hours now. I need another pair of eyes to look into this.
Thanks,
package org.raghav.stuff;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.io.FileUtils;
public class GetFile {
public static void main(String[] args) throws IOException {
File[] files = new File("C:\\Search Files").listFiles();
showFiles(files);
}
public static void showFiles(File[] files) throws IOException {
String line = null;
List<XMLMessage> xmlMessageList = new ArrayList<XMLMessage>();
int i = 0;
//XMLMessage folderFile = new XMLMessage();
try {
for (File file : files) {
if (file.isDirectory()) {
String fileName = file.getName();
System.out.print(fileName);
xmlMessageList.get(i).setFileName(fileName);
//folderFile.setFileName(fileName);
showFiles(file.listFiles()); // Calls same method again.
} else {
xmlMessageList.get(i).setFileDirectory(file.getName() + file.toString());
//folderFile.setFileDirectory(file.getName() + file.toString());
System.out.print("\tFile: " + file.getName()
+ file.toString());
// System.out.println("Directory: " + file.getName());
BufferedReader in = new BufferedReader(new FileReader(file));
while ((line = in.readLine()) != null) {
xmlMessageList.get(i).setFileContent(line);
// folderFile.setFileContent(line);
System.out.print("\t Content:" + line);
}
in.close();
System.out.println();
}
i++;
}
} catch (NullPointerException e) {
e.printStackTrace();
}
System.out.println(xmlMessageList.toString());
}
}
Here is the POJO:
package org.raghav.stuff;
public class XMLMessage {
private String fileDirectory;
private String fileName;
private String fileContent;
public final String FILE_NAME = "fileName";
public final String FILE_DIRECTORY = "fileDirectory";
public XMLMessage(String fileDirectory, String fileName, String fileContent) {
this.fileDirectory = fileDirectory;
this.fileName = fileName;
this.fileContent = fileContent;
}
public XMLMessage() {
}
public String getFileDirectory() {
return fileDirectory;
}
public void setFileDirectory(String fileDirectory) {
this.fileDirectory = fileDirectory;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFileContent() {
return fileContent;
}
public void setFileContent(String fileContent) {
this.fileContent = fileContent;
}
public String toString(){
String returnString = "File Directory: " + fileDirectory + "\n" + "File Name" + fileName + "\n" + "File Content: " + fileContent;
return returnString;
}
/*public String createResponseFileName(String fileName){
int lastDot = fileName.lastIndexOf('.');
String responseFileName = fileName.substring(0, lastDot) + "Response" + fileName.substring(lastDot);
return responseFileName;
}*/
/*public String createResponseFileContent(String fileContent){
this.
}*/
}
You're never populating your list. I suspect you should actually have:
for (File file : files) {
XMLMessage message = new XMLMessage();
xmlMessageList.add(message);
if (file.isDirectory()) {
String fileName = file.getName();
System.out.print(fileName);
message.setFileName(fileName);
//folderFile.setFileName(fileName);
showFiles(file.listFiles()); // Calls same method again.
} else {
... etc, using message instead of xmlMessageList.get(i)
}
}
Then you don't need the i variable at all.
I think Jon Skeet is right.
you never populate your list.
you should use your constructor
XmlMessage m = new XMLMessage( fileDirectory, fileName,fileContent)
xmlMessageList.add(m);
I want to develop logging system in OSGI bundle which can write application errors into file on the HDD.
This is the Activator:
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
public class LoggingSystemApp implements BundleActivator {
LoggingSystemImpl log = null;
#Override
public void start(final BundleContext bc) throws Exception {
debug("Activator started");
ServiceRegistration registerService = bc.registerService(LoggingSystemImpl.class.getName(), new LoggingSystemImpl(), new Properties());
/* Start Logger System */
log = LoggingSystemImpl.getInstance();
log.start();
}
public void stop(BundleContext bc) throws Exception {
boolean ungetService = bc.ungetService(bc.getServiceReference(LoggingSystem.class.getName()));
st.close();
log.stop();
}
private void debug(String msg) {
System.out.println("JDBCBundleActivator: " + msg);
}
}
This is the implementation of the Logging system:
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.sql.Connection;
import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Locale;
import org.DX_57.osgi.LS_27.api.LoggingSystem;
public class LoggingSystemImpl implements LoggingSystem {
public LoggingSystemImpl() {
}
public DataSource ds;
#Override
public void setDataSource(DataSource ds){
this.ds = ds;
}
private final static Calendar calendar = Calendar.getInstance();
private final static String user = System.getenv("USERNAME").toLowerCase();
private final static String sMonth = calendar.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.ENGLISH);
private final static int y = calendar.get(Calendar.YEAR);
// the name of the log file
//private final String logName = sysDrive + "\\fttb_web - " + sMonth.toLowerCase() + ", " + y + ".log";
private final String logName = "logger - " + sMonth.toLowerCase() + ", " + y + ".log";
private static boolean closed;
private static LoggingSystemImpl log = null;
private static BufferedWriter bw = null;
private static FileOutputStream fos = null;
private static OutputStreamWriter osw = null;
/* Utilialize Buffer and wait for data to write */
public void start() throws IOException{
log = LoggingSystemImpl.getInstance();
}
public void stop(){
log.close();
}
public void WriteLog(String WriteString){
log.writeln(WriteString);
}
public void LoggingSystemImpl() throws IOException
{
fos = new FileOutputStream(logName, true);
// set encoding to cyrillic (if available)
if (Charset.isSupported("windows-1251"))
{
osw = new OutputStreamWriter(fos, Charset.forName("windows-1251"));
}
else { osw = new OutputStreamWriter(fos); }
bw = new BufferedWriter(osw, 2048); // 2Mb buffer
}
// intro header for log session
public static synchronized LoggingSystemImpl getInstance() throws IOException
{
boolean exc = false;
try
{
if (log == null || closed)
{
log = new LoggingSystemImpl();
closed = false;
log.writeln("logged in.");
log.nl();
}
}
// catch(IOException x) { exc = true; throw x; }
catch(Exception x) { exc = true; x.printStackTrace(); }
finally
{
if (exc)
{
try
{
if (fos != null) { fos.close(); fos = null; }
if (osw != null) { osw.close(); fos = null; }
if (bw != null) { bw.close(); bw = null; }
}
catch(Exception x) { x.printStackTrace(); }
}
}
return log;
}
public synchronized void nl()
{
try { bw.newLine(); }
catch(IOException x) {x.printStackTrace();}
}
public synchronized void nl(int count)
{
try
{
for (int i = 0; i < count; i++) bw.newLine();
}
catch(IOException x) {x.printStackTrace();}
}
public synchronized void writeln(String s)
{
try { bw.write(getTime() + ": " + s); bw.newLine(); }
catch(IOException x) {x.printStackTrace();}
}
public synchronized void write(String s)
{
try { bw.write(s); }
catch (IOException x) {x.printStackTrace();}
}
public synchronized void close()
{
try
{
if (bw != null)
{
writeln("logged out.");
nl();
bw.flush();
bw.close();
closed = true;
fos = null;
osw = null;
bw = null;
}
}
catch(IOException x) { x.printStackTrace(); }
}
public synchronized boolean isClosed() { return closed; }
public synchronized void writeException(Exception x)
{
writeln("");
write("\t" + x.toString()); nl();
StackTraceElement[] ste = x.getStackTrace();
int j = 0;
for (int i = 0; i < ste.length; i++)
{
if (i < 15) { write("\t\tat " + ste[i].toString()); nl(); }
else { j++; }
}
if (j > 0) { write("\t\t... " + j + " more"); nl(); }
nl(2);
}
private String getTime()
{
Calendar c = Calendar.getInstance();
int month = c.get(Calendar.MONTH) + 1;
int d = c.get(Calendar.DAY_OF_MONTH);
int h = c.get(Calendar.HOUR_OF_DAY);
int m = c.get(Calendar.MINUTE);
int s = c.get(Calendar.SECOND);
int y = c.get(Calendar.YEAR);
String dd = d < 10 ? "0"+d : ""+d;
String hh = h < 10 ? "0"+h : ""+h;
String mm = m < 10 ? "0"+m : ""+m;
String ss = s < 10 ? "0"+s : ""+s;
String sm = month < 10 ? "0"+month : ""+month;
return user + " [" + y + "." + sm + "." + dd + " " + hh + ":" + mm + ":" + ss + "]";
}
}
When I try to compile the code in Netbeans I get this error:
COMPILATION ERROR :
-------------------------------------------------------------
org/DX_57/osgi/LS_27/impl/LoggingSystemImpl.java:[34,7] error: LoggingSystemImpl is not abstract and does not override abstract method SessionRegister(String,String,String) in LoggingSystem
1 error
How I can fix this problem?
Best wishes
P.S
this is the code of the interface
public interface LoggingSystem {
public void setDataSource(DataSource ds);
}
EDIT
Can you tell me do you see any other errors in the code especially the Activator class?
You have to implement the mentioned method in your class. The message says that your class is not abstract bus has not concretely implemented all abstract methods from its parents.
Well, the error message is pretty clear. You can either declare LoggingSystemImpl as abstract or implement the missing method - SessionRegister(String,String,String).
The reason for this is that the interface LoggingSystem has the method SessionRegister(String,String,String) declared. Because it has no implementation, it needs to be implemented in all non-abstract children, including your class.
A quick fix would be:
public class LoggingSystemImpl implements LoggingSystem {
void SessionRegister(String,String,String)
{ //dummy implementation
}
//other methods
}
Looks like there is a method SessionRegister(String,String,String) declared in the interface that you have not implemented... You should probably implement it...
My guess is that if you declared LoggingSystem as you show in your code, then the import in the implementation class is the problem:
import org.DX_57.osgi.LS_27.api.LoggingSystem;
Are you sure that's the interface you're trying to implement?