0

I have class with main method like:

  public class Main {
        public static void main(String[] args) {
            long timeCheck;
            long periodOfTime;

             ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

            long initialDelay = 0; // the time from now to delay execution
            long period = 1; // the period between successive executions 

            scheduler.scheduleAtFixedRate(new FeedReader(img, url, title, price), initialDelay, period, TimeUnit.DAYS);
            ...
            ...
        }
    }

and another class with some code:

public class FeedReader implements Runnable {

    private String img;
    private String url;
    private String title;
    private String price;

    public FeedReader(String img, String url, String title, String price) {
        this.img = img;
        this.url = url;
        this.title = title;
        this.price = price;

    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getImg() {
        return img;
    }

    public void setImg(String img) {
        this.img = img;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

   ...

How to call properly via scheduleAtFixedRate method constructor with existing parameters from FeedReader class? I appreciate any help.

Edited by Max_26

3
Contributors
8
Replies
106
Views
1 Week
Discussion Span
Last Post by Max_26
0

@JamesCherrill, thanks for interest in my question. So, I have two programms parser (FeedReader class) and another programm (with another logic) in parallel and Main class with main method.

  //  class with main method

public class Main {

public static void main(String[] args) {
    long timeCheck;
    long periodOfTime;

    // creation pool with 2 threads
    //A ScheduledExecutorService is capable of scheduling
    // tasks to run either periodically or once after a certain amount of time has elapsed.
    ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

    long initialDelay = 0; // the time from now to delay execution 
    long period = 1; // the period between successive executions

    scheduler.scheduleAtFixedRate(new FeedReader(img, url, title, price), initialDelay, period, TimeUnit.DAYS);

    ...
    // some logic with another class
}

In main I need to call constructor which already has parameters. This is parser (class FeedReader):

public class FeedReader implements Runnable {

private String img;
private String url;
private String title;
private String price;

// constructor which I need to call from main
public FeedReader(String img, String url, String title, String price) {
    this.img = img;
    this.url = url;
    this.title = title;
    this.price = price;
   // feedAdd(img, url, title, price);
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getUrl() {
    return url;
}

public void setUrl(String url) {
    this.url = url;
}

public String getImg() {
    return img;
}

public void setImg(String img) {
    this.img = img;
}

public String getPrice() {
    return price;
}

public void setPrice(String price) {
    this.price = price;
}

@Override
public String toString() {
    return "Article{" +
            "title='" + title + '\'' +
            ", url='" + url + '\'' +
            ", img='" + img + '\'' +
            ", price='" + price + "$" + '\'' +
            '}';
}

public void run() {
    try {
     // some logic to parse
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// here method via feeAdd I'm adding info to database
 public String feedAdd(String img, String url, String title, String price) {

 // parameters that need to get from constructor
        this.img = img;
        this.url = url;
        this.title = title;
        this.price = price;

       // some logic  with connecting to db

long found = collection.count(Document.parse("title"));
        // check if feed exists or not
        if (found == 0) {
            Document doc = new Document("title", title)
                    .append("url", url)
                    .append("img", img)
                    .append("price", price);
            collection.insertOne(doc);
            mongoClient.close();
            System.out.println("Feed not exists in database. Written.");
            return "no_exists";
            // if feed exists
        } else {
            System.out.println("Feed exists in database.");
            mongoClient.close();
            return "exists";
        }
    }
}

Via FeedReader class I get info from website and I need to call parser from main via scheduleAtFixedRate line in main:

scheduler.scheduleAtFixedRate(new FeedReader(img, url, title, price), initialDelay, period, TimeUnit.DAYS);

But I can't do this, because IDE tells me to create again new fields with parameters here:
1.PNG

And I don't know how to call properly existing parameters and don't create new in main. I hope you understand me what I need.

Edited by Max_26

0

I still can't see where you expect to get the initial values of img, url etc from. Is it from the // some logic to parse method? (if so, then the constructor is wrong and you don't need to pass in those parameters)

Edited by JamesCherrill

0

@JamesCherrill, in this place -> // some logic to parse, I have

public void run() {
    try {
 // creating list with articles
List<FeedReader> articleList = new ArrayList<>();
org.jsoup.nodes.Document doc = Jsoup.connect("weblink").get();
// here I'm parsing using variables
String img = ...
String url = ...
String title = ...
String price = ...
...
...
...

// here I'm adding variables that I parsed 
articleList.add(new FeedReader(img, url, title, price));

} catch (IOException e) {
        e.printStackTrace();
}

As I understand, when I'm writing this linearticleList.add(new FeedReader(img, url, title, price));, I'm getting my values that I need from constructor, no? Correct me, please.

Edited by Max_26

0

What have you tried? What errors do you get? The code you submitted doesn't seem to show much effort.

Thanks for interesting too, @tinstaafl.

I tried to write constructor with parameters (which I used above in FeedReader) in another class Article like:

public class FeedReader implements Runnable {
    public void run() {
        try {
            List<Article> articleList = new ArrayList<>();
            org.jsoup.nodes.Document doc = Jsoup.connect("weblink").get();
            ...
            ...
            ...
            articleList.add(new Article(img, url, title, price));

    } catch (IOException e) {
        e.printStackTrace();
    }
}

// to add feed to db
public String feedAdd(String img, String url, String title, String price) {

  // some logic
    long found = collection.count(Document.parse("title"));
    // check if feed exists or not
    if (found == 0) {
        Document doc = new Document("title", title)
                .append("url", url)
                .append("img", img)
                .append("price", price);
        collection.insertOne(doc);
        mongoClient.close();
        System.out.println("Feed not exists in database. Written.");
        return "no_exists";
        // if feed exists
    } else {
        System.out.println("Feed exists in database.");
        mongoClient.close();
        return "exists";
    }
}

class Article {
    private String img;
    private String url;
    private String title;
    private String price;

    public Article(String img, String url, String title, String price) {
        this.img = img;
        this.url = url;
        this.title = title;
        this.price = price;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getImg() {
        return img;
    }

    public void setImg(String img) {
        this.img = img;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Article{" +
                "title='" + title + '\'' +
                ", url='" + url + '\'' +
                ", img='" + img + '\'' +
                ", price='" + price + "$" + '\'' +
                '}';
        }
    }
}

And call from main like:

   public class Main {
        public static void main(String[] args) {
        long timeCheck;
        long periodOfTime;

    // creation pool with 2 threads
    //A ScheduledExecutorService is capable of scheduling
    // tasks to run either periodically or once after a certain amount of time has elapsed.
    ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

    long initialDelay = 0; // the time from now to delay execution
    long period = 1; // the period between successive executions
    scheduler.scheduleAtFixedRate(new FeedReader(), initialDelay, period, TimeUnit.DAYS);

    ...
    ...
  }
}

And the result is:
1.PNG

But in this way method public String feedAdd(String img, String url, String title, String price) from class FeedReader is never used:
3.PNG

I know that I can call feedAdd method directly from constructor like:

 public Article(String img, String url, String title, String price) {
            this.img = img;
            this.url = url;
            this.title = title;
            this.price = price;

      // added line
        feedAdd(String img, String url, String title, String price);
    }
    ...

In this case I didn't get nothing when input:

2.PNG

Edited by Max_26

2

I don't think your problem is with code syntax, it's with the overall design/flow of the app.

Let's try to understand that... (stop me when I go wrong here)

You have a FeedReader class. An instance of that runs via a repeating scheduler to read some web info. When it finds the right info it creates an instance of Article - a class with variables like img, url etc - and adds it to a List.
There's a problem here because the List is a local variable that immediately goes out of scope and gets garbage collected.

You also have a method to add the same info to a database, but for some reason that does not use the Article instance that you created. Maybe that's the problem?

ps: all those set methods in Article are almost certainly a mistake. Why isn't Article immutable?

Edited by JamesCherrill

0

Thank you, James for trying to help. I solved by adding just one string. Anyway, I appreciate your help.

articleList.forEach(article -> feedAdd(article.getImg(), article.getTitle(), article.getUrl(), article.getPrice()));

Edited by Max_26

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.