JsonConverter ObservableList Problem

404 views
Skip to first unread message

Sascha Thiel

unread,
Jan 23, 2015, 10:25:26 AM1/23/15
to dataf...@googlegroups.com
Hi all,

I want to load JSON via a REST and convert it into an ObservableList. I've already tried several combinations but non of them worked form me.

Combo 1:
[{"name":"name 1"},{"name":"name 2"}]

JsonConverter<TestData> converter = new JsonConverter<TestData>(null, TestData.class);
RestSource<TestData> source = RestSourceBuilder.create().converter(converter).host(HOST).path(PATH).build();

ListDataProviderBuilder<TestData> odpb = ListDataProviderBuilder.<TestData> create();

ListProperty<TestData> resultProperty = new SimpleListProperty<TestData>();
odpb
.dataReader(source).resultList(resultProperty);

ListDataProvider<TestData> provider = odpb.build();
Worker<ObservableList<TestData>> worker = provider.retrieve();

Here i do not get any error but also no data, the resultProperty.get() will be null. This is actually my preferred combo. So I would be very happy if you have an idea why this isn't working.

Combo 2:
{"items":[{"name":"name 1"},{"name":"name 2"}]}

JsonConverter<TestData> converter = new JsonConverter<TestData>("items", TestData.class);
RestSource<TestData> source = RestSourceBuilder.create().converter(converter).host(HOST).path(PATH).build();

ListDataProviderBuilder<TestData> odpb = ListDataProviderBuilder.<TestData> create();

ListProperty<TestData> resultProperty = new SimpleListProperty<TestData>();
odpb
.dataReader(source).resultList(resultProperty);

ListDataProvider<TestData> provider = odpb.build();
Worker<ObservableList<TestData>> worker = provider.retrieve();

Result:
Exception in thread "JavaFX Application Thread" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at java.util.AbstractCollection.addAll(AbstractCollection.java:344)
at javafx.beans.binding.ListExpression.addAll(ListExpression.java:266)
at io.datafx.core.concurrent.PublishingTask$1.run(PublishingTask.java:69)
at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/1613403397.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
at com.sun.javafx.application.PlatformImpl$$Lambda$46/785992331.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
at com.sun.glass.ui.win.WinApplication$$Lambda$37/2052915500.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)

So basically this combo seems to be the closest, but why is it trying to add something to an AbstractList? Internally  it is creating a ObservableList... Where is the problem here?
public PublishingTask() {
    this(new SimpleListProperty<T>(FXCollections.<T>observableArrayList()));
}

This is my used setup:
<dependency>
  <groupId>org.glassfish</groupId>
  <artifactId>javax.json</artifactId>
  <version>1.0.4</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>io.datafx</groupId>
  <artifactId>datasources</artifactId>
  <version>8.0.7</version>
  <scope>compile</scope>
</dependency>


Thanks in advance.

Hendrik Ebbers

unread,
Jan 23, 2015, 10:37:06 AM1/23/15
to dataf...@googlegroups.com
Hi,

don't use 8.0.7. I missed totally that this is in maven central. Please use version 8.0. 
8.0.7. was a missed release for 8.0-beta7. I think I must find a way to remove this from maven central.

We will answer your question as fast as we can :)

Sascha Thiel

unread,
Jan 23, 2015, 11:10:47 AM1/23/15
to dataf...@googlegroups.com
Changed it to 8.0. The issue remains. I'm looking forward to your answer. ;-)

Thanks for the quick response.

Johan Vos

unread,
Jan 23, 2015, 3:06:31 PM1/23/15
to dataf...@googlegroups.com
Hi,

Parsing JSON can be difficult, we should provide more debug. You can set the loglevel of io.datafx to FINER to get more logs.
Here are 2 things:
1) in your first example, instead of passing null as tag in the converter, pass "", e.g.
JsonConverter<TestData> converter = new JsonConverter<TestData>("", TestData.class);
2) in both examples, don't use a ListProperty but an ObservableList:
    ObservableList<TestData> resultProperty = FXCollections.observableArrayList();

Let me know if this helps?

- Johan

Sascha Thiel

unread,
Jan 24, 2015, 3:50:14 AM1/24/15
to dataf...@googlegroups.com
Hi,

I only did the changes you described and now it is working perfectly. My changed code is now:
JsonConverter<TestData> converter = new JsonConverter<TestData>("", TestData.class);
RestSource<TestData> source = RestSourceBuilder.create().converter(converter).host(HOST).path(PATH).build();

ListDataProviderBuilder<TestData> odpb = ListDataProviderBuilder.<TestData> create();

ObservableList<TestData> resultProperty = FXCollections.observableList(new ArrayList<TestData>());

odpb
.dataReader(source).resultList(resultProperty);

ListDataProvider<TestData> provider = odpb.build();
Worker<ObservableList<TestData>> worker = provider.retrieve();

Thanks a lot for the quick support.

Rufus J

unread,
Jul 23, 2015, 3:40:34 PM7/23/15
to DataFX, johan...@gmail.com
Hi Johan,

I've been trying to work through a JSON parsing example for days now without success.

You mention setting the log levels of io.datafx to FINER.  Could you describe exactly how to do this?

This is my logging.properties file:

handlers = java.util.logging.ConsoleHandler

.level = ALL

java
.util.logging.ConsoleHandler.level = ALL
java
.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
 
javafx
.level = INFO
io
.datafx.level = FINER

This is my first time posting a question.  Thanks,

Adolfo S

unread,
Jul 24, 2015, 12:29:25 AM7/24/15
to DataFX, johan...@gmail.com, sailsan...@gmail.com
So I figured this out:

My immediate problem was that I did not have org.glassfish.json providers in my classpath.  Since I was getting no logging, I was able to discover my problem like this:

        Worker<ObservableList<Account>> worker = listDataProvider.retrieve();

        worker
.stateProperty().addListener(new ChangeListener<Worker.State>() {
           
@Override
           
public void changed(ObservableValue<? extends State> observable,
                   
State oldState, State newState) {
               
System.out.println(String.format("%s %s", oldState.toString(),
                        newState
.toString()));
       
               
if (newState == State.FAILED) {
                    worker
.getException().printStackTrace();
                   
String exp = worker.getException().toString();
                   
System.out.println(exp);
               
} else if (newState == State.SUCCEEDED) {
                   
// and here your checks, eg
                   
ListProperty<Account> result = listDataProvider.getData();
                   
System.out.println("AccountsController 0.1 " + result.getSize());
               
}
           
}
       
});

The Listener printed the exception upon the worker State changing to FAILED.

OK, hope that helps someone.  Thanks for reading!

TKP

unread,
Apr 3, 2016, 1:54:19 PM4/3/16
to DataFX, johan...@gmail.com, sailsan...@gmail.com
Hi All,

I'm also testing (for hours) a javaFX8 app with DataFX8 as Sasha did and the version 8.0 as suggested Hendrik.
I use his code and also Adolfo one to get the STATE code in the WORKER but the state is FAILED.

I have JBOSS as a standalone server, running kitchensink webservices.
This link (http://localhost:8080/fmServer/rest/members/0) give me the JSON response from the server:

{"id":0,"name":"John Smith","email":"john....@mailinator.com","phoneNumber":"2125551212"}

So I use the following code to get the JSON with DataFX8.0:
private void callRESTService1() throws IOException {
String HOST = "http://localhost:8080";
String PATH = "fmServer/rest/members/0";

JsonConverter<Member> converter = new JsonConverter<Member>("", Member.class);
RestSource<Member> source = RestSourceBuilder.create().converter(converter).host(HOST).path(PATH).build();
ListDataProviderBuilder<Member> odpb = ListDataProviderBuilder.<Member> create();
ObservableList<Member> resultProperty = FXCollections.observableArrayList();
odpb.dataReader(source).resultList(resultProperty);
ListDataProvider<Member> provider = odpb.build();

Worker<ObservableList<Member>> worker = provider.retrieve();
worker.stateProperty().addListener(new ChangeListener<Worker.State>() {
public void changed(ObservableValue<? extends State> observable, State oldState, State newState) {
System.out.println(String.format("%s %s", oldState.toString(), newState.toString()));
if (newState == State.FAILED) {
worker.getException().printStackTrace();
String exp = worker.getException().toString();
System.out.println(exp);
} else if (newState == State.SUCCEEDED) {
ObjectProperty<Member> result = null;
provider.setResultObjectProperty((ObjectProperty) result);

System.out.println(result.toString() );
}
}
});
}

When running the code, the console shows and ERROR:

SCHEDULED RUNNING
RUNNING FAILED
javax.json.JsonException: Provider org.glassfish.json.JsonProviderImpl not found
javax.json.JsonException: Provider org.glassfish.json.JsonProviderImpl not found
at javax.json.spi.JsonProvider.provider(JsonProvider.java:97)
at javax.json.Json.createReader(Json.java:220)
at io.datafx.io.converter.JsonConverter.initialize(JsonConverter.java:100)
at io.datafx.io.converter.JsonConverter.initialize(JsonConverter.java:62)
at io.datafx.io.InputStreamDataReader.setInputStream(InputStreamDataReader.java:109)
at io.datafx.io.RestSource.createRequest(RestSource.java:118)
at io.datafx.io.RestSource.next(RestSource.java:141)
at io.datafx.provider.ListDataProvider$2.callTask(ListDataProvider.java:245)
at io.datafx.core.concurrent.PublishingTask.call(PublishingTask.java:61)
at io.datafx.core.concurrent.PublishingTask.call(PublishingTask.java:44)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at javafx.concurrent.Service.lambda$null$492(Service.java:725)
at java.security.AccessController.doPrivileged(Native Method)
at javafx.concurrent.Service.lambda$executeTask$493(Service.java:724)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: org.glassfish.json.JsonProviderImpl
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at javax.json.spi.JsonProvider.provider(JsonProvider.java:94)
... 17 more

I don't know it FAILED and WHY org.glassfish.json API need to be used there as it worked for Adolfo.

I went into the this link trying to find out where the API is used :http://grepcode.com/snapshot/repo1.maven.org/maven2/io.datafx/datasources/8.0/
And there is no class from the io.datafx.io.converter and  io.datafx.io.provider use org.glassfish.json

Furthermore, when I comment the the code as follow :
// JsonConverter<Member> converter = new JsonConverter<Member>("", Member.class);
// RestSource<Member> source = RestSourceBuilder.create().converter(converter).host(HOST).path(PATH).build();
// ListDataProviderBuilder<Member> odpb = ListDataProviderBuilder.<Member> create();
// ObservableList<Member> resultProperty = FXCollections.observableArrayList();
// odpb.dataReader(source).resultList(resultProperty);
// final ListDataProvider<Member> listDataProvider = odpb.build();
// final Worker<ObservableList<Member>> worker = listDataProvider.retrieve();

and replace by this:    
final InputStreamConverter<Member> inputStreamConverter = null;
RestSource<Member> source = new RestSource("http://localhost:8080/fmServer/rest/members/0", inputStreamConverter);
    final ObjectDataProvider provider = new ObjectDataProvider(source);
    final Worker<ObservableList<Member>> worker = provider.retrieve(); 

there is no ERROR, and the console the worker response is SUCCEDED but I have nothing in provider variable.

Is there something wrong in my code ?
Any help would be appreciated.
Thanks
Reply all
Reply to author
Forward
0 new messages