rewriting a series in JavaFX linechart - javafx-2

I have a JavaFX app that utilizes the lineChart chart. I can write a chart to the app, and clear it, but when I want to write a new series and have it displayed, I get an error,
java.lang.IllegalArgumentException: Children: duplicate children added:
I understand the meaning, but not how to fix (I am very new to Java, let alone to FX).
Here is the relevant code from my controller (minus some class declarations):
(method called by the 'submit' button in chart tab window)
#FXML
private void getEngDataPlot(ActionEvent event) {
//check time inputs
boolean start = FieldVerifier.isValidUtcString(startRange.getText());
boolean end = FieldVerifier.isValidUtcString(endRange.getText());
type = engData.getValue().toString();
// Highlight errors.
startRangeMsg.setTextFill(Color.web(start ? "#000000" : "#ff0000"));
endRangeMsg.setTextFill(Color.web(end ? "#000000" : "#ff0000"));
if (!start || !end ) {
return;
}
// Save the preferences.
Preferences prefs = Preferences.userRoot().node(this.getClass().getName());
prefs.put("startRange", startRange.getText());
prefs.put("endRange", endRange.getText());
prefs.put("engData", engData.getValue().toString());
StringBuilder queryString = new StringBuilder();
queryString.append(String.format("edit out",
startRange.getText(),
endRange.getText()));
queryString.append(type);
log(queryString.toString());
// Start the query task.
submitEngData.setDisable(true);
// remove the old series.
engChart.getData().clear();
engDataProgressBar.setDisable(false);
engDataProgressBar.setProgress(-1.0);
//ProgressMessage.setText("Working...");
Thread t = new Thread(new EngDataPlotTask(queryString.toString()));
t.setDaemon(true);
t.start();
}
(the task called by above method:)
public EngDataPlotTask(String query) {
this.query = query;
}
#Override
protected Void call() {
try {
URL url = new URL(query);
String inputLine = null;
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream()));
// while ( in.readLine() != null){
inputLine = in.readLine(); //}
Gson gson = new GsonBuilder().create();
DataObject[] dbin = gson.fromJson(inputLine, DataObject[].class);
in.close();
for (DataObject doa : dbin) {
series.getData().add(new XYChart.Data(doa.danTime, doa.Fvalue));
}
xAxis.setLabel("Dan Time (msec)");
} catch (Exception ex) {
log(ex.getLocalizedMessage());
}
Platform.runLater(new Runnable() {
#Override
public void run() {
submitEngData.setDisable(false);
// do some pretty stuff
String typeName = typeNameToTitle.get(type);
series.setName(typeName);
// put this series on the chart
engChart.getData().add(series);
engDataProgressBar.setDisable(true);
engDataProgressBar.setProgress(1.0);
}
});
return null;
}
}
The chart draws a first time, clears, and then the exception occurs. Requested stack trace follows:
Exception in runnable
java.lang.IllegalArgumentException: Children: duplicate children added: parent = Group#8922394[styleClass=plot-content]
at javafx.scene.Parent$1.onProposedChange(Unknown Source)
at com.sun.javafx.collections.VetoableObservableList.add(Unknown Source)
at com.sun.javafx.collections.ObservableListWrapper.add(Unknown Source)
at javafx.scene.chart.LineChart.seriesAdded(Unknown Source)
at javafx.scene.chart.XYChart$2.onChanged(Unknown Source)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(Unknown Source)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(Unknown Source)
at com.sun.javafx.collections.ObservableListWrapper.callObservers(Unknown Source)
at com.sun.javafx.collections.ObservableListWrapper.add(Unknown Source)
at com.sun.javafx.collections.ObservableListWrapper.add(Unknown Source)
at edu.arizona.lpl.dan.DanQueryToolFX.QueryToolController$EngDataPlotTask$1.run(QueryToolController.java:231)
at com.sun.javafx.application.PlatformImpl$4.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(Unknown Source)
at com.sun.glass.ui.win.WinApplication$2$1.run(Unknown Source)
at java.lang.Thread.run(Thread.java:722)
Any ideas what I am doing wrong. I am a RANK NEWBIE, so please take that into account if you wish to reply. Thank you!

It took long time to find a workaround solution for this issue.
Please add below piece of code and test:
engChart.getData().retainAll();
engChart.getData().add(series);

My guess about the root cause according to your incomplete code is this line:
engChart.getData().add(series);
You should add series only once in initialize block for instance. But I think in your task thread, you are adding the already added same series again and having that mentioned exception. If your aim is to refresh the only series data, then just manipulate the series, getting it by engChart.getData().get(0); and delete that line in the code.

Once you add the series to the graph all you do is edit the series. Don't add it to the graph again.
The graph will follow whatever happens to the series i.e. just change the series data and the graph will automatically reflect the changes.

Related

Why does Spring batch multithreaded step break additional repository hibernate queries in ItemProcessor?

I working on transforming a gigantic DB2 schema with about 30-40 tables into a streamlined JSON format via Spring Batch. My process works just fine with one thread, but as soon as I increase the thread pool size to enable multi-threading my step, my ItemProcessor breaks down with infuriatingly cryptic and incomprehensible errors.
I just don't understand how my Processor could possibly not be thread-safe: I'm not maintaining state anywhere, I'm just making a few extra repository calls to enrich the data, since I couldn't get the reader to pull in everything I need. And one such repository call is throwing an ArrayIndexOutOfBoundsException! I even added a #Transactional annotation to my processor and called it using Java's multithreaded java.util.concurrent.ExecutorService - works just fine there too.
I just can't seem to figure out why my Spring Batch multithreaded step would break my Item Processor's simple repository queries. I even intermittently get LazyLoading exceptions! Isn't an Item Processor supposed to be wrapped in a transaction? And intermittently I see absolutely nonsensical exceptions about class-cast exceptions, where a one to many mapping is returning the wrong Entity type! Again, this all works perfectly for the same data set in one thread. Is my configuration wrong?
java.lang.ArrayIndexOutOfBoundsException: 1765
at org.hibernate.engine.internal.EntityEntryContext.reentrantSafeEntityEntries(EntityEntryContext.java:319) ~[hibernate-core-5.3.14.Final.jar!/:5.3.14.Final]
at org.hibernate.engine.internal.StatefulPersistenceContext.reentrantSafeEntityEntries(StatefulPersistenceContext.java:1156) ~[hibernate-core-5.3.14.Final.jar!/:5.3.14.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:145) ~[hibernate-core-5.3.14.Final.jar!/:5.3.14.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:83) ~[hibernate-core-5.3.14.Final.jar!/:5.3.14.Final]
at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:46) ~[hibernate-core-5.3.14.Final.jar!/:5.3.14.Final]
at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1433) ~[hibernate-core-5.3.14.Final.jar!/:5.3.14.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1519) ~[hibernate-core-5.3.14.Final.jar!/:5.3.14.Final]
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1538) ~[hibernate-core-5.3.14.Final.jar!/:5.3.14.Final]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1506) ~[hibernate-core-5.3.14.Final.jar!/:5.3.14.Final]
at org.hibernate.query.Query.getResultList(Query.java:132) ~[hibernate-core-5.3.14.Final.jar!/:5.3.14.Final]
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:129) ~[spring-data-jpa-2.1.14.RELEASE.jar!/:2.1.14.RELEASE]
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:91) ~[spring-data-jpa-2.1.14.RELEASE.jar!/:2.1.14.RELEASE]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:136) ~[spring-data-jpa-2.1.14.RELEASE.jar!/:2.1.14.RELEASE]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:125) ~[spring-data-jpa-2.1.14.RELEASE.jar!/:2.1.14.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605) ~[spring-data-commons-2.1.14.RELEASE.jar!/:2.1.14.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.14.RELEASE.jar!/:2.1.14.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor$$Lambda$541/246846952.get(Unknown Source) ~[na:na]
at org.springframework.data.repository.util.QueryExecutionConverters$$Lambda$540/1619129136.apply(Unknown Source) ~[na:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.14.RELEASE.jar!/:2.1.14.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.1.14.RELEASE.jar!/:2.1.14.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda$539/1493625851.proceedWithInvocation(Unknown Source) ~[na:na]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) ~[spring-tx-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:144) ~[spring-data-jpa-2.1.14.RELEASE.jar!/:2.1.14.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$ExposeRepositoryInvocationInterceptor.invoke(CrudMethodMetadataPostProcessor.java:364) ~[spring-data-jpa-2.1.14.RELEASE.jar!/:2.1.14.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) ~[spring-data-commons-2.1.14.RELEASE.jar!/:2.1.14.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) [spring-aop-5.1.12.RELEASE.jar!/:5.1.12.RELEASE]
...
Here's my properties file:
#I don't want all my jobs run, I want to specify which one via an environment variable
spring.batch.job.enabled=false
spring.main.allow-bean-definition-overriding=true
spring.main.web-application-type=none
#If I set this count to 1, everything works just fine.
process.thread.count=4
process.page.size=25
hibernate.jdbc.fetch_size=100
process.chunk.size=25
process.publish.limit=200
My configuration class:
#Configuration
public class FullProductSyncBatchJobConfig {
#Bean
#StepScope
public ItemStreamReader<LegacyProduct> productReader(
LegacyProductRepository legacyProductRepository,
#Value("#{jobParameters[pageSize]}") Integer pageSize,
#Value("#{jobParameters[limit]}") Integer limit) {
RepositoryItemReader<LegacyProduct> legacyProductRepositoryReader = new RepositoryItemReader<>();
legacyProductRepositoryReader.setRepository(legacyProductRepository);
legacyProductRepositoryReader.setMethodName("findAllRelevantProducts");
legacyProductRepositoryReader.setSort(new HashMap<String, Sort.Direction>() {{
put("id.guid", Sort.Direction.ASC);
put("id.modelNumber", Sort.Direction.ASC);
}});
legacyProductRepositoryReader.setPageSize(pageSize);
if(limit > 0) legacyProductRepositoryReader.setMaxItemCount(limit);
legacyProductRepositoryReader.setSaveState(false);
return legacyProductRepositoryReader;
}
#Bean
#StepScope
public ItemProcessor<LegacyProduct, StreamlinedProduct> productDocumentBuilder(
SupplierRepository supplierRepository) {
return new StreamlinedProductBuilder(supplierRepository);
}
#Bean
#StepScope
public ItemWriter<StreamlinedProduct> productDocumentPublisher(
GcpPubsubPublisherService publisherService) {
return new StreamlinedProductPublisher(publisherService);
}
#Bean
public Step fullProductSync(ItemStreamReader<LegacyProduct> productReader,
ItemProcessor<LegacyProduct, StreamlinedProduct> productDocumentBuilder,
ItemWriter<StreamlinedProduct> productDocumentPublisher,
StepBuilderFactory stepBuilderFactory,
TaskExecutor syncProcessThreadPool,
PlatformTransactionManager jpaTransactionManager,
#Value("${process.chunk.size:100}") Integer chunkSize,
#Value("${process.publish.timeout.retry.limit:2}") int timeoutRetryLimit,
#Value("${process.failure.limit:20}") int maximumProcessingFailures) {
return stepBuilderFactory.get("fullProductSync")
.transactionManager(jpaTransactionManager)
.<GtinVendor, AbstractProduct>chunk(chunkSize)
.reader(productReader)
.processor(productDocumentBuilder)
.writer(productDocumentPublisher)
.faultTolerant()
.retryLimit(timeoutRetryLimit)
.retry(TimeoutException.class)
.skipPolicy(new SyncProcessSkipPolicy(maximumProcessingFailures))
.listener(new SyncProcessSkipListener()) // <== just logs them right now
.taskExecutor(syncProcessThreadPool)
.build();
}
#Bean
public Job fullProductSyncJob(Step fullProductSync,
JobBuilderFactory jobBuilderFactory) {
return jobBuilderFactory.get("fullProductSync")
.start(fullProductSync)
.build();
}
}
And my processor class:
#Slf4j
public class StreamlinedProductBuilder implements ItemProcessor<LegacyProduct, StreamlinedProduct> {
private DimensionRepository dimensionRepository;
public LegacyProductBuilder(DimensionRepository dimensionRepository) {
this.dimensionRepository = dimensionRepository;
}
public StreamlinedProduct process(LegacyProduct legacyProduct) {
StreamlinedProduct streamlinedProduct = new StreamlinedProduct();
streamlinedProduct.setPrimarySupplierNumber(parsePrimarySupplierNumber(product.getSuppliers()));
attachProductDimensions(streamlinedProduct, legacyProduct);
return streamlinedProduct;
}
private int parsePrimarySupplierNumber(List<Supplier> suppliers) {
/* This intermittently throws a ClassCastException when using multiple threads,
* saying that a Description can't be cast a Supplier... WHAT??! HOW???! How does
* getSuppliers() ever return a list of a completely different one-to-many entity????
*/
for(Supplier supplier : suppliers) {
if(supplier.isPrimary()) return supplier.getId();
}
return -1;
}
private void attachProductDimensions(LegacyProduct legacyProduct,
StreamlinedProduct streamlinedProduct) {
// The following line occasionally throws the ArrayOutOfBounds index I mentioned above. WHY?
// Works just fine in one thread...
List<Dimension> dimensions= dimensionRepository.findByProductIdAndModel(
legacyProduct.getId().getGuid(), legacyProduct.getId().getModelNumber());
Map<String, Double> dimensionsAsMap = new HashMap<>();
for (Description description : descriptions ) {
dimensionsAsMap.put(dimension.getName(), dimension.getValue());
}
streamlinedProduct.setDimensions(dimensionsAsMap);
}
}
My repository:
#Repository
public interface DimensionRepository extends PagingAndSortingRepository<ProductDimension, DimensionCompositePK> {
#Transactional(isolation = Isolation.READ_UNCOMMITTED) // <== fails with or without this
#Query(value = "select d.name as name, d.value as value " +
"from {h-schema}product p left join {h-schema}dimension d " +
"on p.guid = d.product_guid and p.model_number = d.product_model_number " +
"where p.guid = :guid and p.model_number = :model", nativeQuery = true)
List<Dimension> findVendorsByGtinGlnCountry(#Param("guid") String guid,
#Param("modelNumber") Integer model);
}
I don't know what was going on or why I was seeing exceptions suggesting Spring was trying to fill certain oneToMany relationships with the wrong Entity class from a different oneToMany relationship.
But regardless, adopting the Spring Batch driver-query pattern seems to have fixed things for me. I was under the impression that the same transaction was shared for a given chunk across the reader, processor, and writer. But I think that assumption was incorrect - each chunk of each stage has its own transaction.
So now my reader simply pulls in all relevant IDs of my entity class, and the processor goes out and fetches the oneToMany relationships for that entity.

Liferay model listener - on after update handler loop

I have created custom model listener for DLFileEntry in Liferay 6.2 GA6. However, the onAfterUpdate method is called repeatedly even when no change has been made on DLFileEntry.
Let me describe the situation:
The file entry is changed through the content administration in Liferay
The onAfterUpdate method is triggered (this is OK)
The onAfterUpdate method is triggered again and again - even though there is no update made on this entry
I' ve dumped the stack trace when the (unexpected) update event happenes. It looks like the onAfterUpdate is triggered by incrementViewCounter(..)method, which is triggered by BufferedIncrementRunnable class
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1365)
at eu.package.hook.model.listener.DLFileEntryModelListener.onAfterUpdate(DLFileEntryModelListener.java:63)
at eu.package.hook.model.listener.DLFileEntryModelListener.onAfterUpdate(DLFileEntryModelListener.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.liferay.portal.kernel.bean.ClassLoaderBeanHandler.invoke(ClassLoaderBeanHandler.java:67)
at com.sun.proxy.$Proxy865.onAfterUpdate(Unknown Source)
at com.liferay.portal.service.persistence.impl.BasePersistenceImpl.update(BasePersistenceImpl.java:340)
at com.liferay.portlet.documentlibrary.service.impl.DLFileEntryLocalServiceImpl.incrementViewCounter(DLFileEntryLocalServiceImpl.java:1450)
at sun.reflect.GeneratedMethodAccessor2034.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62)
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.increment.BufferedIncreasableEntry.proceed(BufferedIncreasableEntry.java:48)
at com.liferay.portal.increment.BufferedIncrementRunnable.run(BufferedIncrementRunnable.java:65)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
I have read the documenantation about the bufferend increment in portal.properties docs page. It's not recommended to disable this feature.
I have also thought about checking if any relevant change has been made on DLFileEntry object in model listener method. I just wanted to check, if there is any configuration that could be made to bypass the onAfterUpdate method when it's triggered by incrementViewCounter method.
Any help is appreciated.
Update:
On after update method:
private void createMessage(DLFileEntry model, String create) {
JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
jsonObject.put("action", create);
jsonObject.put("id", model.getFileEntryId());
MessageBusUtil.sendMessage(SUPIN_MESSAGE_LISTENER_DESTINATION, jsonObject);
}
#Override
public void onAfterUpdate(DLFileEntry model) throws ModelListenerException {
if (LOG.isTraceEnabled()) {
URL[] urls = ((URLClassLoader) (Thread.currentThread().getContextClassLoader())).getURLs();
LOG.trace("Current thread classpath is: " + StringUtils.join(urls, ","));
}
LogMF.info(LOG, "File entry on update event - id {0}" , new Object[]{model.getFileEntryId()});
Thread.dumpStack();
createMessage(model, UPDATE);
}
Here is the message listener (message bus) which performs the on after update actions:
private void createOrUpdate(DLFileEntry model, String createOrUpdate) {
try {
initPermissionChecker(model);
LOG.info("Document " + model.getFileEntryId() + " " + createOrUpdate + "d in Liferay. Creating entry in Safe.");
long documentInSafe;
if (UPDATE.equalsIgnoreCase(createOrUpdate)) {
documentInSafe = (long) model.getExpandoBridge().getAttribute(EXPANDO_SAFE_DOCUMENT_ID);
if (documentInSafe > 0) {
safeClient.updateDocumentInSafe(model);
} else {
documentInSafe = safeClient.createDocumentInSafe(model);
}
} else {
documentInSafe = safeClient.createDocumentInSafe(model);
}
LOG.info("Document " + createOrUpdate +"d successfully with id " + documentInSafe);
saveSafeIDToExpando(model, documentInSafe);
} catch (Exception e) {
LOG.error("Unable to safe ID of document in Safe", e);
}
}
private void saveSafeIDToExpando(DLFileEntry model, long documentInSafe) throws SystemException {
try {
ExpandoTable table = ExpandoTableLocalServiceUtil.getDefaultTable(model.getCompanyId(), DLFileEntry.class.getName());
ExpandoColumn column = ExpandoColumnLocalServiceUtil.getColumn(table.getTableId(), EXPANDO_SAFE_DOCUMENT_ID);
ExpandoValueLocalServiceUtil.addValue(model.getCompanyId(), table.getTableId(), column.getColumnId(), model.getClassPK(), String.valueOf(documentInSafe));
LOG.info("ID of document in Safe updated in expando attribute");
} catch (PortalException e) {
LOG.error("Unable to save Safe document ID in expando." , e);
;
}
}
private void initPermissionChecker(DLFileEntry model) throws Exception {
User safeAdminUser = UserLocalServiceUtil.getUserByScreenName(model.getCompanyId(), SAFE_ADMIN_SCREEN_NAME);
PermissionChecker permissionChecher = PermissionCheckerFactoryUtil.create(safeAdminUser);
PermissionThreadLocal.setPermissionChecker(permissionChecher);
PrincipalThreadLocal.setName(safeAdminUser.getUserId());
CompanyThreadLocal.setCompanyId(model.getCompanyId());
LOG.info("Permission checker successfully initialized.");
}
I suggest this, but I am not sure if it resolves your case.
I've changed the body of your own method onAfterUpdate.
Using TransactionCommitCallbackRegistryUtil you can detach the model update request from the subsequent createMessage logic.
public void onAfterUpdate(DLFileEntry model) throws ModelListenerException {
TransactionCommitCallbackRegistryUtil.registerCallback(new Callable() {
#Override
public Void call() throws Exception {
createMessage(model, UPDATE);
}
}

Bind SCA Component Properties In Waveform Control Panel

I am trying to create a Waveform Control Panel to change the properties of its components. I attempted to apply the example in the Redhawk documentation for a Component Control Panel, but for some reason I get a java.lang.NullPointerException when running the plugin. The error occurs when I attempt to bind the text field to a component property, the exact line where the error occurred is in the comments of the code (at the very bottom).
public class TestControlPanel extends AbstractScaContentEditor<ScaWaveform> {
private ScaWaveform waveform;
private ScaComponent myComponent;
private Text propertyValueField;
private EMFDataBindingContext context;
/**
* {#inheritDoc}
*/
#Override
public void createPartControl(final Composite main) {
main.setLayout(new GridLayout(2, false));
Group controlGroup = new Group(main, SWT.SHADOW_ETCHED_OUT);
controlGroup.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
controlGroup.setText("Controls");
createControlGroup(controlGroup);
}
private void createControlGroup(Composite parent) {
parent.setLayout(new GridLayout(2, false));
EObject input = getInput();
if (input instanceof ScaWaveform) {
// make local copy of waveform
waveform = (ScaWaveform) input;
try {
waveform.refresh(null, RefreshDepth.FULL);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
label = new Label(parent,SWT.None);
label.setText("Property Value:");
propertyValueField = new Text(parent, SWT.BORDER | SWT.FILL);
myComponent = waveform.getScaComponent("myComponent_1");
if(myComponent != null)
{
IObservableValue observable = SCAObservables.observeSimpleProperty(myComponent, "propertyId");
IObservableValue targetObservable = WidgetProperties.text(SWT.Modify).observeDelayed(5000,propertyValueField);
if(observable != null && targetObservable != null)
{
// ***** THE BELOW LINE CAUSES A java.lang.NullPointerException ERROR *****
context.bindValue(targetObservable, observable);
// ***** THE ABOVE LINE CAUSES A java.lang.NullPointerException ERROR *****
}
}
}
}
My original guess for the reason for this error was that one of the IObservableValue variables (e.g. targetObservable or observable) was null, which is why I check to make sure the values are not null before binding them. However, this didn't fix the problem and I still got the same error.
From what code I can see it seems as though your field varible "context" was never initialized.
Simply call the no argument constructor:
context = new EMFDataBindingContext();
It appears that the context variable is null. I see that you define "context" at the top of the class, but I didn't see where it has been set.

javafx IllegalArguementException when popup is open and mouse is clicked on the background stage

on click of it i am launching a popup. Pop has a dynamically created stackpane with a tableview. If i double click a row in table or i enter esc its working fine.
Issue is when i click anywhere on the background stage it gives me following error. How to close the popup when i click on the stage from where the popup is launched. Please suggest.
java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1435)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:33)
at javafx.event.Event.fireEvent(Event.java:171)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3324)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3164)
at javafx.scene.Scene$MouseHandler.access$1900(Scene.java:3119)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1559)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2261)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:228)
at com.sun.glass.ui.View.handleMouseEvent(View.java:528)
at com.sun.glass.ui.View.notifyMouse(View.java:922)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
at java.lang.Thread.run(Thread.java:722)
Below is my code
public void trkTripNoBtnClick(ActionEvent ae){
StackPane st = new StackPane();
final TableView<GatePassDTO> tripListTableView = new TableView<GatePassDTO>();
TableColumn<GatePassDTO,String> colTrkTripNo = new TableColumn<GatePassDTO,String>();
TableColumn<GatePassDTO,Date> colGatePassDttm = new TableColumn<GatePassDTO,Date>();
TableColumn<GatePassDTO,String> colTruckNo = new TableColumn<GatePassDTO,String>();
TableColumn<GatePassDTO,String> colBat = new TableColumn<GatePassDTO,String>();
colTrkTripNo.setText("Trip No");
colTrkTripNo.setCellValueFactory(new PropertyValueFactory<GatePassDTO,String>("tourPlnNo"));
colGatePassDttm.setText("Gate Pass Dttm");
colGatePassDttm.setCellValueFactory(new PropertyValueFactory<GatePassDTO,Date>("gatePassDttm"));
colTruckNo.setText("Truck");
colTruckNo.setCellValueFactory(new PropertyValueFactory<GatePassDTO,String>("haulPmNo"));
colBat.setText("BAT ID");
colBat.setCellValueFactory(new PropertyValueFactory<GatePassDTO,String>("batId"));
List<GatePassDTO> tripsList = GateIn.getGatePassReference().gateIn_tourPlnNoLookUp(1);
tripListTableView.getColumns().addAll(colTrkTripNo,colGatePassDttm,colTruckNo,colBat);
tripListTableView.setItems(FXCollections.observableList(tripsList));
final Popup popup = new Popup();
popup.setX(txtTrkTripNo.getLayoutX());
popup.setY(txtTrkTripNo.getLayoutY()+txtTrkTripNo.getHeight()+30);
colTrkTripNo.prefWidthProperty().bind(tripListTableView.widthProperty().multiply(0.20));
colGatePassDttm.prefWidthProperty().bind(tripListTableView.widthProperty().multiply(0.45));
colTruckNo.prefWidthProperty().bind(tripListTableView.widthProperty().multiply(0.15));
colBat.prefWidthProperty().bind(tripListTableView.widthProperty().multiply(0.20));
tripListTableView.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent t) {
if(t.getClickCount() == 2 && tripListTableView.getSelectionModel().getSelectedItem() !=null){
GatePassDTO g = tripListTableView.getSelectionModel().getSelectedItem();
popup.hide();
txtTrkTripNo.setText(g.getTourPlnNo());
getTripDetails(txtTrkTripNo.getText());
}
}
});
tripListTableView.addEventHandler(KeyEvent.KEY_PRESSED,new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent t) {
if(t.getCode() == KeyCode.ESCAPE)
popup.hide();
}
});
/*Label lblFind = new Label("Find");
TextField txtfind = new TextField();
st.getChildren().add(lblFind);
st.getChildren().add(txtfind);*/
st.getChildren().add(tripListTableView);
VBox v = new VBox(5);
v.getChildren().addAll(st);
popup.getContent().addAll(v);
popup.show(GateIn.primaryStage);
}
you have to check focus property for stage...
try this its worked
stage.focusedProperty().addListener(new ChangeListener<Boolean>
() {
#Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
if(t1==false)
{
System.out.println("focus losted");
btn.getScene().getWindow().hide();
}
}
});

Powermock newbie/NoClassDefFoundError when mocking Apache DefaultHttpClient

I'm new to object mocking, and trying to create unit tests for some legacy code. I'm trying to use powermock for the first time, and encountering a NoClassDefFoundError on line 69 ( DefaultHttpClient mockClient = mock(DefaultHttpClient.class);) (see trace below).
Can anyone give me a hand and point me in the right direction?
#RunWith(PowerMockRunner.class)
#PrepareForTest(LoginClient.class)
public class LoginClientTest {
Properties props = null;
#Before
public void setUp() throws FileNotFoundException, IOException {
props = new Properties();
props.load(new FileInputStream("./src/test/resources/LoginClient/default.properties"));
}
/**
* Method description
* #throws Exception
*
*/
#Test
public void loginPositiveTest()
throws Exception {
DefaultHttpClient mockClient = mock(DefaultHttpClient.class);
HttpResponse mockResponse = mock(HttpResponse.class);
StatusLine mockStatusLine = mock(StatusLine.class);
Header[] headers = new BasicHeader[2];
headers[0] = new BasicHeader("Set-Cookie", "COOKIE-DATA");
headers[1] = new BasicHeader("Set-Cookie", "COOKIE-DATA-2");
whenNew(DefaultHttpClient.class).withNoArguments().thenReturn(mockClient);
when(mockClient.execute(isA(HttpUriRequest.class))).thenReturn(mockResponse);
when(mockResponse.getStatusLine()).thenReturn(mockStatusLine);
when(mockStatusLine.getStatusCode()).thenReturn(HttpStatus.SC_OK);
when(mockResponse.getAllHeaders()).thenReturn(headers);
LoginClient client = new LoginClient();
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(props.getProperty("user"),
props.getProperty("password"));
String result = client.getCookie(creds.getUserName(), creds.getPassword());
System.out.println(result);
assertNotNull(result);
}
}
java.lang.NoClassDefFoundError: org.apache.http.impl.client.DefaultHttpClient$$EnhancerByMockitoWithCGLIB$$221fdb68
at sun.reflect.GeneratedSerializationConstructorAccessor6.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:521)
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:40)
at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:59)
at org.mockito.internal.creation.jmock.ClassImposterizer.createProxy(ClassImposterizer.java:111)
at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:51)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:100)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:58)
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:138)
at [REDACTED].clients.LoginClientTest.loginPositiveTest(LoginClientTest.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:615)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:307)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:112)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:73)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:102)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Problem appears to be solved by changing from java5 (IBM Websphere) to Sun/Oracle Java6.

Resources