I'm trying to implement a producer-consumer model by using Hazelcast.
The producer puts an item to queue and the consumer consumes it using take() method.
I close the consumer application and start again. The consumer retrieves the previously consumed item from the queue.
I tried the Hazelcast Ringbuffer and I see the same behavior.
Is there a way to force to remove the consumed item from the queue in Hazelcast?
Thanks in advance
Producer.java:
public class Producer implements MembershipListener {
private HazelcastInstance hzInstance;
private Cluster cluster;
private IAtomicLong counter;
private IQueue<Data> dataQueue;
private IMap<String, List<Data>> dataByConsumerId;
public static void main(String[] args) {
Producer producer = new Producer();
Scanner scanIn = new Scanner(System.in);
while (true) {
String cmd = scanIn.nextLine();
if (cmd.equals("QUIT")) {
break;
} else if (cmd.equals("ADD")) {
long x = producer.counter.addAndGet(1);
producer.dataQueue.add(new Data(x, x + 1));
}
}
scanIn.close();
}
public Producer() {
hzInstance = Hazelcast.newHazelcastInstance(configuration());
counter = hzInstance.getCPSubsystem().getAtomicLong("COUNTER");
dataByConsumerId = hzInstance.getMap("CONSUMER_DATA");
dataQueue = hzInstance.getQueue("DATA_QUEUE");
cluster = hzInstance.getCluster();
cluster.addMembershipListener(this);
}
public Config configuration() {
Config config = new Config();
config.setInstanceName("hazelcast-instance");
MapConfig mapConfig = new MapConfig();
mapConfig.setName("configuration");
mapConfig.setTimeToLiveSeconds(-1);
config.addMapConfig(mapConfig);
return config;
}
#Override
public void memberAdded(MembershipEvent membershipEvent) {
}
#Override
public void memberRemoved(MembershipEvent membershipEvent) {
String removedConsumerId = membershipEvent.getMember().getUuid().toString();
List<Data> items = dataByConsumerId.remove(removedConsumerId);
if (items == null)
return;
items.forEach(item -> {
System.out.println("Push data to recover :" + item.toString());
dataQueue.add(item);
});
}
}
Consumer.java:
public class Consumer {
private String id;
private HazelcastInstance hzInstance;
private IMap<String, List<Data>> dataByConsumerId;
private IQueue<Data> dataQueue;
public Consumer() {
hzInstance = Hazelcast.newHazelcastInstance(configuration());
id = hzInstance.getLocalEndpoint().getUuid().toString();
dataByConsumerId = hzInstance.getMap("CONSUMER_DATA");
dataByConsumerId.put(id, new ArrayList<Data>());
dataQueue = hzInstance.getQueue("DATA_QUEUE");
}
public Config configuration() {
Config config = new Config();
config.setInstanceName("hazelcast-instance");
MapConfig mapConfig = new MapConfig();
mapConfig.setName("configuration");
mapConfig.setTimeToLiveSeconds(-1);
config.addMapConfig(mapConfig);
return config;
}
public static void main(String[] args) {
Consumer consumer = new Consumer();
try {
consumer.run();
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
private void run() {
while (true) {
System.out.println("Take queue item...");
try {
var item = dataQueue.take();
System.out.println("New item taken:" + item.toString());
var dataInCluster = dataByConsumerId.get(id);
dataInCluster.add(item);
dataByConsumerId.put(id, dataInCluster);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Data.java:
public class Data implements Serializable {
private static final long serialVersionUID = -975095628505008933L;
private long x, y;
public Data(long x, long y) {
super();
this.x = x;
this.y = y;
}
public long getX() {
return x;
}
public void setX(long x) {
this.x = x;
}
public long getY() {
return y;
}
public void setY(long y) {
this.y = y;
}
#Override
public String toString() {
return "Data [x=" + x + ", y=" + y + "]";
}
}
Related
I am trying to set the spring boot application which will pool the csv . i do not see any activity happning in the spring boot application nor on filezilla SFTP server but if I change the same code to FTP then it works
#Component
#EnableIntegration
public class IntegrationConfiguration {
#Autowired
FTPConfigProperties ftpConfigProperties;
#Autowired
private BeanFactory beanFactory;
#Value("classpath:certificate.crt")
Resource certficateFile;
#Bean
public SessionFactory<ChannelSftp.LsEntry> ftpSessionFactory() {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory();
factory.setHost("127.0.0.1");
factory.setPort(990);
factory.setUser("abhinav");
factory.setPassword("nssdw");
factory.setPrivateKey(certficateFile);
factory.setAllowUnknownKeys(true);
return new CachingSessionFactory<ChannelSftp.LsEntry>(factory, 100000);
}
#Bean
public SftpInboundFileSynchronizer ftpInboundFileSynchronizer() {
SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(ftpSessionFactory());
fileSynchronizer.setDeleteRemoteFiles(false);
fileSynchronizer.setRemoteDirectory("/");
fileSynchronizer.setFilter(filter());
fileSynchronizer.setDeleteRemoteFiles(false);
fileSynchronizer.setPreserveTimestamp(true);
fileSynchronizer.setBeanFactory(beanFactory);
return fileSynchronizer;
}
//here the poller is configured
#Bean
#InboundChannelAdapter(channel = "fromSftpChannel", poller = #Poller(fixedDelay = "10000"))
public MessageSource<File> ftpMessageSource() throws Exception {
SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
ftpInboundFileSynchronizer());
source.setLocalDirectory(new File("ftp-inbound"));
source.setAutoCreateLocalDirectory(true);
source.setMaxFetchSize(1);
source.setBeanFactory(beanFactory);
source.setUseWatchService(true);
return source;
}
public CompositeFileListFilter<ChannelSftp.LsEntry> filter() {
CompositeFileListFilter<ChannelSftp.LsEntry> filter = new CompositeFileListFilter<ChannelSftp.LsEntry>();
filter.addFilter(new SftpSimplePatternFileListFilter("*.csv"));
filter.addFilter(acceptOnceFilter());
filter.addFilter(new LastModifiedLsEntryFileListFilter());
return filter;
}
#Bean
public SftpPersistentAcceptOnceFileListFilter acceptOnceFilter() {
SftpPersistentAcceptOnceFileListFilter filter = new SftpPersistentAcceptOnceFileListFilter(metadataStore(),"ftpPersistentAcceptOnce");
filter.setFlushOnUpdate(true);
return filter;
}
#Bean
public ConcurrentMetadataStore metadataStore() {
PropertiesPersistingMetadataStore propertiesPersistingMetadataStore = new PropertiesPersistingMetadataStore();
propertiesPersistingMetadataStore.setBaseDirectory("./metastore");
propertiesPersistingMetadataStore.setFileName("ftpStream.properties");
return propertiesPersistingMetadataStore;
}
#Bean
#ServiceActivator(inputChannel = "jobChannel", outputChannel = "nullChannel")
protected JobLaunchingMessageHandler launcher(JobLauncher jobLauncher) {
return new JobLaunchingMessageHandler(jobLauncher);
}
}
here the next call where I trigger the spring batch then it goes to service actuator
#Component
public class FileToJobTransformer implements ApplicationContextAware {
private ApplicationContext context;
#Autowired
private Job job;
#Transformer(inputChannel = "fromSftpChannel", outputChannel = "jobChannel")
public JobLaunchRequest transform(File aFile) throws Exception {
String fileName = aFile.getName();
JobParameters jobParameters = new JobParametersBuilder().addString(
"input.file", aFile.getAbsolutePath()).toJobParameters();
JobLaunchRequest request = new JobLaunchRequest(job, jobParameters);
return request;
}
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}
the custome code is as follow
public class LastModifiedLsEntryFileListFilter implements FileListFilter<ChannelSftp.LsEntry> {
private static final long DEFAULT_AGE = 60;
private volatile long age = DEFAULT_AGE;
public long getAge() {
return this.age;
}
public void setAge(long age) {
setAge(age, TimeUnit.SECONDS);
}
public void setAge(long age, TimeUnit unit) {
this.age = unit.toSeconds(age);
}
#Override
public List<ChannelSftp.LsEntry> filterFiles(ChannelSftp.LsEntry[] files) {
System.out.println("files = [" + files.length + "]");
List<ChannelSftp.LsEntry> list = new ArrayList<ChannelSftp.LsEntry>();
long now = System.currentTimeMillis() / 1000;
for (ChannelSftp.LsEntry file : files) {
if (file.getAttrs()
.isDir()) {
continue;
}
int lastModifiedTime = file.getAttrs()
.getMTime();
if (lastModifiedTime + this.age <= now) {
list.add(file);
}
}
Collections.reverse(list);
ArrayList<ChannelSftp.LsEntry> oneElementList = new ArrayList<ChannelSftp.LsEntry>(1) ;
oneElementList.add(list.get(0));
return oneElementList;
}
}
I am reading java 8 in action and the author references this link: http://mail.openjdk.java.net/pipermail/lambda-dev/2013-November/011516.html
and writes his own stream forker that looks like this:
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class Main {
public static void main(String... args) {
List<Person> people = Arrays.asList(new Person(23, "Paul"), new Person(24, "Nastya"), new Person(30, "Unknown"));
StreamForker<Person> forker = new StreamForker<>(people.stream())
.fork("All names", s -> s.map(Person::getName).collect(Collectors.joining(", ")))
.fork("Age stats", s -> s.collect(Collectors.summarizingInt(Person::getAge)))
.fork("Oldest", s -> s.reduce((p1, p2) -> p1.getAge() > p2.getAge() ? p1 : p2).get());
Results results = forker.getResults();
String allNames = results.get("All names");
IntSummaryStatistics stats = results.get("Age stats");
Person oldest = results.get("Oldest");
System.out.println(allNames);
System.out.println(stats);
System.out.println(oldest);
}
interface Results {
<R> R get(Object key);
}
static class StreamForker<T> {
private final Stream<T> stream;
private final Map<Object, Function<Stream<T>, ?>> forks = new HashMap<>();
public StreamForker(Stream<T> stream) {
this.stream = stream;
}
public StreamForker<T> fork(Object key, Function<Stream<T>, ?> f) {
forks.put(key, f);
return this;
}
public Results getResults() {
ForkingStreamConsumer<T> consumer = build();
try {
stream.sequential().forEach(consumer);
} finally {
consumer.finish();
}
return consumer;
}
private ForkingStreamConsumer<T> build() {
List<BlockingQueue<T>> queues = new ArrayList<>();
Map<Object, Future<?>> actions =
forks.entrySet().stream().reduce(
new HashMap<>(),
(map, e) -> {
map.put(e.getKey(),
getOperationResult(queues, e.getValue()));
return map;
},
(m1, m2) -> {
m1.putAll(m2);
return m1;
}
);
return new ForkingStreamConsumer<>(queues, actions);
}
private Future<?> getOperationResult(List<BlockingQueue<T>> queues,
Function<Stream<T>, ?> f) {
BlockingQueue<T> queue = new LinkedBlockingQueue<>();
queues.add(queue);
Spliterator<T> spliterator = new BlockingQueueSpliterator<>(queue);
Stream<T> source = StreamSupport.stream(spliterator, false);
return CompletableFuture.supplyAsync(() -> f.apply(source));
}
}
static class ForkingStreamConsumer<T> implements Results, Consumer<T> {
static final Object END_OF_STREAM = new Object();
private final List<BlockingQueue<T>> queues;
private final Map<Object, Future<?>> actions;
ForkingStreamConsumer(List<BlockingQueue<T>> queues,
Map<Object, Future<?>> actions) {
this.queues = queues;
this.actions = actions;
}
public void finish() {
accept((T) END_OF_STREAM);
}
#Override
public <R> R get(Object key) {
try {
return ((Future<R>) actions.get(key)).get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#Override
public void accept(T t) {
queues.forEach(q -> q.add(t));
}
}
static class BlockingQueueSpliterator<T> implements Spliterator<T> {
private final BlockingQueue<T> q;
public BlockingQueueSpliterator(BlockingQueue<T> q) {
this.q = q;
}
#Override
public boolean tryAdvance(Consumer<? super T> action) {
T t;
while (true) {
try {
t = q.take();
break;
} catch (InterruptedException e) {
}
}
if (t != ForkingStreamConsumer.END_OF_STREAM) {
action.accept(t);
return true;
}
return false;
}
#Override
public Spliterator<T> trySplit() {
return null;
}
#Override
public long estimateSize() {
return 0;
}
#Override
public int characteristics() {
return 0;
}
}
static class Person {
private int age;
private String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
#Override
public String toString() {
return String.format("Age: %d, name: %s", age, name);
}
}
}
How the code written by the author works:
First, we create a StreamForker out of a stream. Then we fork 3 operations, saying what we want to do on that stream in parallel. In our case, our data model is the Person{age, name} class and we want to perform 3 actions:
Get a string of all names
Get age statistics
Get the oldest person
we then call the forker.getResults() method, that applies a StreamForkerConsumer to the stream, spreading its elements into 3 blocking queues, which are then turned into 3 streams and processed in parallel.
My question is, does this approach have any advantage over just doing this:
Future<String> allNames2 =
CompletableFuture.supplyAsync(() -> people.stream().map(Person::getName).collect(Collectors.joining(", ")));
Future<IntSummaryStatistics> stats2 =
CompletableFuture.supplyAsync(() -> people.stream().collect(Collectors.summarizingInt(Person::getAge)));
Future<Person> oldest2 =
CompletableFuture.supplyAsync(() -> people.stream().reduce((p1, p2) -> p1.getAge() > p2.getAge() ? p1 : p2).get());
?
For me this doesn't make much sense with an array list as stream source.
If the stream source is a big file that you process with
StreamForker<Person> forker = new StreamForker<>(
java.nio.file.Files.lines(Paths.get("somepath"))
.map(Person::new))
.fork(...)
then it could prove beneficial since you would process the whole file only once, whereas with three seperat calls to Files.lines(...) you would read the file three times.
how can i block the put method when cache reloading is being called.
Example: These are dummy classes not the actual.
Caching class
public class Class1 {
private static Map<Integer, Integer> map = new HashMap<>();
public Class1() {
for (int i = 0; i < 20; i++) {
map.put(i, ++i);
}
}
public void reload() throws InterruptedException {
Map<Integer, Integer> exist = map;
System.out.println("are you waiting ");
System.out.println("waiting over");
map = new HashMap<>();
for (Map.Entry<Integer, Integer> entry : exist.entrySet()) {
map.put(entry.getKey(), entry.getValue());
}
for (int i = 100; i < 120; i++) {
map.put(i, ++i);
}
}
public Map<Integer, Integer> getMap() {
return map;
}
}
Class initializing the cache
public class Class2 {
private static Class1 cache = new Class1();;
public Class1 getCache() {
return cache;
}
public void reload() throws InterruptedException {
cache.reload();
}
}
class using the cache
package com.diaryreaders.corejava.algorithms.dp;
public class Class3 {
public static void main(String[] args) {
final Class2 klass = new Class2();
Runnable runn1 = new Runnable() {
#Override
public void run() {
int i = 50, j = 50;
while (i < 100) {
System.out.println("I am stuck due to lock");
klass.getCache().getMap().put(i++, j++);
System.out.println(klass.getCache().getMap());
}
}
};
Runnable runn2 = new Runnable() {
#Override
public void run() {
try {
System.out.println("Calling reloading");
klass.reload();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t1 = new Thread(runn1);
Thread t2 = new Thread(runn2);
t1.start();
t2.start();
}
}
As thread t2 is calling reloading, t1 should be blocked i.e cache put method be blocked till reloading completes
I cant seem to find the problem on the code but it the server is not displaying anything. It displays the catch. Client seems find and it sets the players name and score and sends it but I cant seem to find the issue on this one why server is not displaying the name and score.
Here is my Client:
public class Client
{
private static final int BUFSIZE = 64;
public static void main(String[] args) throws IOException
{
try
{
int scores;
Scanner in = new Scanner(System.in);
Socket clntSock = new Socket("127.0.0.1", 6000);
System.out.println("What is the filename?");
String input = in.nextLine();
Scanner fileInput = new Scanner(new File(input));
ObjectOutputStream out = new
ObjectOutputStream(clntSock.getOutputStream());
Player playerObject = new Player();
playerObject.setName(fileInput.nextLine());
System.out.println(""+playerObject.getName());
for (int i = 0; i < 5; i++)
{
scores = Integer.parseInt(fileInput.nextLine());
playerObject.setScore(scores);
System.out.println(""+playerObject.getScores().get(i));
}
out.writeObject(playerObject);
in.close();
fileInput.close();
out.close();
clntSock.close();
}
catch ( UnknownHostException ex )
{
System.out.println( "Unknown host" );
}
}
}
and my Host:
public class Host
{
private static final int BUFSIZE = 64;
public static void main(String[] args) throws IOException
{
// Step 1: Create a ServerSocket.
ServerSocket servSock = new ServerSocket(6000);
PrintStream fileOut = new PrintStream("Datafromclient.txt");
try
{
// Step 2: Wait for a connection..
Socket clntSock = servSock.accept();
// Step 3: Get input and output streams.
System.out.println("Step 3: Get object input stream.,");
ObjectInputStream objectIn = new
ObjectInputStream(clntSock.getInputStream());
Player playerObjct = (Player)objectIn.readObject();
System.out.println("The name of Player: "+playerObjct.getName());
for(int i=0; i <5; i++)
{
System.out.println("Scores:"+playerObjct.getScores().get(i));
}
objectIn.close();
clntSock.close();
// Step 5: Close connection
objectIn.close();
clntSock.close();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
System.err.println(e);
}
}
}
My player class:
public class Player
private String name;
private int playerId;
private int bestScore;
private static int numberOfPlayers = 0;
private ArrayList<Integer> scores = new ArrayList<Integer>();
/* -------------- CONSTRUCTOR --------------------------------------
*/
public Player()
{
numberOfPlayers++;
playerId = numberOfPlayers;
}
public Player(String name)
{
this.name = name;
}
//Create set method for setName
public void setName(String name)
{
this.name = name;
}
//Create set method for setScores
public void setScore(int score)
{
scores.add(score);
}
//Create get method for getPlayerId
public int getPlayerId()
{
return this.playerId;
}
//Create get method for getName
public String getName()
{
return this.name;
}
//Create get method for getScores
public ArrayList<Integer> getScores()
{
return scores;
}
//Create get method for getBestScore
public int getBestScore()
{
calculateBestScore();
return bestScore;
}
//Method to expose the value of numberOfPlayers
public static int getNumberOfPlayers()
{
return numberOfPlayers;
}
//Create get method for calcualteAverage
public double calculateAverage()
{
Integer sum = 0;
if(!scores.isEmpty())
{
for(Integer score : scores)
{
sum += score;
}
return sum.doubleValue() / scores.size();
}
return sum;
}
public void calculateBestScore()
{
bestScore = Collections.max(scores);
}
}
I was missing
import java.io.Serializable;
public class Player implements Serializable
now its working.
I Would like to execute a background task which executes multiple background tasks. What i am actually trying to do is execute a background process which executes some code for every Object in a list, and does it within a fixed thread pool. So, for example, i have 100 users in the list and i am executing code for each of them concurrently but no more than 5 at the same time.
Therefore i am using two service/task pairs: One service/task for executing on the whole list of users, this service uses a fixed thread pool as its executor and executes a series of second service/task pairs for every user in the list.
like in the following example:
class MainService extends Service<List<User>> {
private List<User> users;
public MainService(List<User> users) { this.users=users; }
protected Task<List<User>> createTask(){
return new MainTask(this.users)
}
}
class Maintask extends Task<List<User>> {
private List<User> users;
private Executor executor;
public MainTask(List<User> users) {
this.users=users;
this.executor=Executors.newFixedThreadPool(5);
}
protected List<User> call() throws Exception {
for (User user : this.users) {
System.out.println("Starting single service");
SingleService service=new SingleService(user)
service.setExecutor(this.executor);
service.start();
System.out.println("Single service started");
}
}
}
class SingleService extends Service<User> {
private User user;
public SingleService(User user) { this.user=user; }
protected Task<User> createTask() {
return new SingleTask(this.user)
}
}
class SingleTask extends Task<User> {
private User user;
public SingleTask(User user) { this.user=user; }
protected User call() throws Exception() {
// Do some work
}
}
The code executes up to the moment when first "starting single service" is printed, the "single service started" message is not being printed at all. As far as i see the SingleService is started, but its createTask() is not being executed at all. Am i making some mistake here?
Well, I am trying to do the same thing, in different context... launch multiple services from a single main Service.
I've overridden all methods of Service, and this is my printout:
Service must only be used from the FX Application Thread {from onFailed() method}
Service does not run on FX thread, but can only be called from the FX thread.
Therefore, all Services and Tasks called within a Service or Task will not be executed.
This is my work around:
public class FXComponentImporter extends Service<Void> implements JarImporter {
//Scanner<T> = Service<List<Class<T>>>
private Scanner<Node> nodeScanner = null;
private Scanner<Paint> paintScanner = null;
private Scanner<Animation> animationScanner = null;
private static int nodeCount = 0, paintCount = 0, animationCount = 0;
private final ObservableMap<String, Class<?>> foundComponents = FXCollections.observableHashMap();
public FXComponentImporter() {
this(null);
}
public FXComponentImporter(File file) {
if (file != null) {
try {
this.nodeScanner = new Scanner<>(file, Node.class);
this.paintScanner = new Scanner<>(file, Paint.class);
this.animationScanner = new Scanner<>(file, Animation.class);
} catch (IOException ex) {
Logger.getLogger(FXComponentImporter.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
File f = importJar();
try {
this.nodeScanner = new Scanner<>(f, Node.class);
this.paintScanner = new Scanner<>(f, Paint.class);
this.animationScanner = new Scanner<>(f, Animation.class);
} catch (IOException ex) {
Logger.getLogger(FXComponentImporter.class.getName()).log(Level.SEVERE, null, ex);
}
}
this.scanningDone.bind(this.nodeScanningDone.and(this.paintScanningDone.and(this.animationScanningDone)));
this.scanningDone.addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue) {
if(scanningDone.isBound()){
scanningDone.unbind();
}
start();
scanningDone.removeListener(this);
}
}
});
startScanning();
}
#Override
protected Task<Void> createTask() {
return new Task<Void>() {
#Override
protected Void call() throws Exception {
Map<String, Class<?>> map = new HashMap<>();
List<Class<Node>> nodes = new ArrayList<>();
List<Class<Paint>> paints = new ArrayList<>();
List<Class<Animation>> anims = new ArrayList<>();
CountDownLatch latch = new CountDownLatch(1);
//Platform needed due to Service only accessed from FX thread
Platform.runLater(() -> {
try {
//FX Stuff done here
nodes.addAll(nodeScanner.getMatchingClasses());
paints.addAll(paintScanner.getMatchingClasses());
anims.addAll(animationScanner.getMatchingClasses());
} finally {
latch.countDown();
}
});
latch.await();
this.updateMessage("Scanning for Nodes ... ");
nodes.stream().forEach(n -> {
if(n != null){
map.putIfAbsent(n.getSimpleName(), n);
}
nodeCount++;
});
this.updateMessage("Found : " + nodeCount + " Nodes ... ");
this.updateMessage("Scanning for Paints ... ");
paints.stream().forEach(p -> {
if(p != null){
map.putIfAbsent(p.getSimpleName(), p);
}
paintCount++;
});
this.updateMessage("Found : " + paintCount + " Paints ... ");
this.updateMessage("Scanning for Animations ... ");
anims.stream().forEach(a -> {
if(a != null){
map.putIfAbsent(a.getSimpleName(), a);
}
animationCount++;
});
this.updateMessage("Found : " + animationCount + " Animations ... ");
foundComponents.putAll(map);
return null;
}
};
}
#Override
protected void executeTask(Task<Void> task) {
super.executeTask(task);
System.out.println(getClass().getSimpleName() + " is Executing " + task.getTitle());
}
#Override
protected void cancelled() {
super.cancelled();
System.out.println(getClass().getSimpleName() + " was Cancelled ... ");
}
#Override
protected void running() {
super.running();
System.out.println(getClass().getSimpleName() + " is Running ... ");
}
#Override
protected void ready() {
super.ready();
System.out.println(getClass().getSimpleName() + " is Ready! ... ");
}
#Override
protected void scheduled() {
super.scheduled();
System.out.println(getClass().getSimpleName() + " is Scheduled ... ");
}
#Override
protected void failed() {
super.failed();
System.out.println(getException().getMessage());
}
#Override
protected void succeeded() {
super.succeeded();
System.out.println("Importing Succeeded ... with: " + foundComponents.entrySet().size() + " results.\n");
foundComponents.forEach((s, c) -> {
System.out.println(c.getSuperclass().getSimpleName() + " >> " + s + " : " + c.getSimpleName());
});
}
#Override
public void restart() {
super.restart();
System.out.println(getClass().getSimpleName() + " is Restarting ... ");
}
private void startScanning() {
nodeScanner.stateProperty().addListener(nsl);
paintScanner.stateProperty().addListener(psl);
animationScanner.stateProperty().addListener(asl);
nodeScanner.start();
paintScanner.start();
animationScanner.start();
}
private final BooleanProperty scanningDone = new SimpleBooleanProperty(false);
private final BooleanProperty nodeScanningDone = new SimpleBooleanProperty(false);
private final BooleanProperty paintScanningDone = new SimpleBooleanProperty(false);
private final BooleanProperty animationScanningDone = new SimpleBooleanProperty(false);
private final ChangeListener nsl = new ChangeListener<Worker.State>() {
#Override
public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
if (newValue.equals(State.SUCCEEDED)) {
nodeScanningDone.set(true);
nodeScanner.stateProperty().removeListener(this);
}
}
};
private final ChangeListener psl = new ChangeListener<Worker.State>() {
#Override
public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
if (newValue.equals(State.SUCCEEDED)) {
paintScanningDone.set(true);
paintScanner.stateProperty().removeListener(this);
}
}
};
private final ChangeListener asl = new ChangeListener<Worker.State>() {
#Override
public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
if (newValue.equals(State.SUCCEEDED)) {
animationScanningDone.set(true);
animationScanner.stateProperty().removeListener(this);
}
}
};
public ObservableMap<String, Class<?>> getFoundComponents() {
return foundComponents;
}
}
and my Interface if you wanna try it out:
public interface JarImporter {
public static File defaultDirectory = new File(System.getProperty("user.home"));
public static final FileChooser.ExtensionFilter classfilter = new FileChooser.ExtensionFilter("Jar files", "*.jar");
static FileChooser defaultFileChooser(){
FileChooser fc = new FileChooser();
fc.getExtensionFilters().add(classfilter);
fc.setInitialDirectory(defaultDirectory);
return fc;
}
public default File importJar(){
File jar = defaultFileChooser().showOpenDialog(null);
if(jar != null){
return jar;
}else{
return null;
}
}
}
Hope this helps.. though just looked at Question date, and was a while ago...