I am implementing headless force update of the eclipse application. I have used the P2Util class from https://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2Fp2_startup.htm but my code is returning null pointer exception at ProvisioningJob job = operation.getProvisioningJob(null); the job object is coming null. Does anyone know the possible reason for this null object.
public class P2Util {
// XXX Check for updates to this application and return a status.
static IStatus checkForUpdates(IProvisioningAgent agent, IProgressMonitor monitor) throws OperationCanceledException {
ProvisioningSession session = new ProvisioningSession(agent);
// the default update operation looks for updates to the currently
// running profile, using the default profile root marker. To change
// which installable units are being updated, use the more detailed
// constructors.
UpdateOperation operation = new UpdateOperation(session);
SubMonitor sub = SubMonitor.convert(monitor,
"Checking for application updates...", 200);
IStatus status = operation.resolveModal(sub.newChild(100));
if (status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) {
return status;
}
if (status.getSeverity() == IStatus.CANCEL)
throw new OperationCanceledException();
if (status.getSeverity() != IStatus.ERROR) {
// More complex status handling might include showing the user what updates
// are available if there are multiples, differentiating patches vs. updates, etc.
// In this example, we simply update as suggested by the operation.
ProvisioningJob job = operation.getProvisioningJob(null);
status = job.runModal(sub.newChild(100));//null pointer here
if (status.getSeverity() == IStatus.CANCEL)
throw new OperationCanceledException();
}
return status;
}
}
I am calling this method as follows.
private Integer checkUpdate(final String updateServerURL, final IProvisioningAgent provisioningAgent, ProgressMonitorSplash monitor) {
returnValue = IApplication.EXIT_OK;
final IRunnableWithProgress runnable = new IRunnableWithProgress() {
#Override
public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
P2Util.addRepository(provisioningAgent, updateServerURL);
final IStatus updateStatus = P2Util.checkForUpdates(provisioningAgent, monitor);
if (updateStatus.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) {
logger.debug("No Updates");
} else if (updateStatus.getSeverity() != IStatus.ERROR) {
logger.debug("Updates applied, attempting restart");
returnValue = IApplication.EXIT_RESTART;
} else {
logger.error(updateStatus.getMessage());
}
}
};
try {
monitor.run(true, runnable);
} catch (final InvocationTargetException e) {
e.printStackTrace();
} catch (final InterruptedException e) {
logger.error("interrupted: " + e.getMessage());
}
return returnValue;
}
where I am creating ProvisingAgent using EclipseContext
final IEclipseContext localContext = EclipseContextFactory.getServiceContext(Activator.getContext());
final IProvisioningAgent provisioningAgent = getService(localContext, IProvisioningAgent.class);
String env = System.getProperty("env").toLowerCase();
String repo = System.getProperty("validUrl." + env);
if ( repo == null ){
repo = System.getProperty("validUrl");
}
if ( repo != null ){
ret = checkUpdate(repo, provisioningAgent, sp);
if ( ret == IApplication.EXIT_RESTART ){
logger.info("Update successful, restarting...");
return ret;
}
}
The javadoc on the UpdateOperation#getProvisioningJob(IProgressMonitor) says:
* #return a job that can be used to perform the provisioning operation. This may be <code>null</code>
* if the operation has not been resolved, or if a plan could not be obtained when attempting to
* resolve. If the job is null and the operation has been resolved, then the resolution result
* will explain the problem.
Related
Class MnetLdapHelper {
private static volatile MnetLDAPService ldapSvc = null;
public MnetLdapHelper() throws Throwable {
if (ldapSvc == null) {
synchronized(MnetLdapHelper.class) {
if (ldapSvc == null) {
setup();
}
}
}
}
public void setup() throws Throwable {
PropertyManager appProp = PropertyUtil.getInstance()
.getPropertyManager();
try {
sLog.info("MnetLdapHelper setup(+) ");
ldapHost = appProp.getStringProperty("LDAP", "Host");
ldapSslPOrt = Integer.valueOf(appProp.getStringProperty("LDAP", "Port"));
ldapPort = Integer.valueOf(appProp.getStringProperty("LDAP", "NonSSLPort"));
baseDn = appProp.getStringProperty("LDAP", "BaseDN");
appCUID = appProp.getStringProperty("LDAP", "AppCUID");
appPasswd = appProp.getStringProperty("LDAP", "AppPassword");
groupBaseDn = appProp.getStringProperty("LDAPGROUPS", "GroupBaseDN");
String appDN = null;
int minConnInt = 1;
int maxConnInt = 10;
if (minConn != null && minConn.length() > 0) {
minConnInt = Integer.parseInt(minConn);
}
if (maxConn != null && maxConn.length() > 0) {
maxConnInt = Integer.parseInt(maxConn);
}
ldapSvc = new MnetLDAPService(ldapHost, ldapPort, false, null,
null, baseDn, minConnInt, maxConnInt);
LDAPEntry appEntry = ldapSvc.getUser(appCUID, null, null);
if (appEntry == null) {
sLog.error("Non-existent application CUID: [" + appCUID +
"], throw new Exception...");
throw new Exception("Non-existent application CUID: [" +
appCUID + "]");
}
appDN = appEntry.getDN();
sLog.info("appDN is: " + InfoSecValidation.cleanLogMessage(appDN));
// Empty the non-SSL connection pool
ldapSvc.finalize();
ldapSvc = new MnetLDAPService(ldapHost, ldapSslPOrt, true, appDN,
appPasswd, baseDn);
// ldapSvc.setDisconnect(Boolean.parseBoolean(ldapApiDisconnectConnectionFlag));
ldapSvc.setDisconnect(false);
// ldapSvc.setUserSearchAttributes(IDATTRS);
} catch (LDAPException ldEx) {
if (ldapSvc != null) {
ldapSvc.finalize();
ldapSvc = null;
}
sLog.error(
"LDAPException caught in setup(), throw new DocsServiceException... " +
ldEx.errorCodeToString(), ldEx);
throw ldEx;
} catch (Throwable ex) {
if (ldapSvc != null) {
ldapSvc.finalize();
ldapSvc = null;
}
sLog.error(
"Throwable caught in setup(), throw new DocsServiceException",
ex);
throw ex;
}
}
}
This above code is being used in my application . Previously I was getting code correctness : Double check locking fortify issue when I was not using volatile , then I found that we can solve this problem by using volatile keyword but issue is still there can someone help me what is wrong here
There is a flaw in your solution. The problem is that the setup() method can be called at any time by any thread, and that it changes the state of the private static by a side-effect.
A better solution is to change setup() to create and return a MnetLdapHelper instance, and the assign the result of to the static.
class MnetLdapHelper {
private static volatile MnetLDAPService ldapSvc = null;
public MnetLdapHelper() {
if (ldapSvc == null) {
synchronized (MnetLdapHelper.class) {
if (ldapSvc == null) {
ldapSvc = setup();
}
}
}
}
private MnetLDAPService setup() {
MnetLDAPService res = ...
// initialize it
return res;
}
}
Now it is debatable whether Fortify's is correct in reporting your version as an incorrectly implemented double-checked lock. It could be that the heuristic that Fortify is using is incorrect.
But that is moot if you can rewrite the code to satisfy Fortify. I think you will find that my version will do that.
I would also take issue with any method or constructor that is declared as throws Throwable. You should change this to list only the checked exceptions that you expect to be thrown.
Finally the way that you are using a static here is likely you cause problems for unit testing MnetLdapHelper or other code that uses a MnetLdapHelper instance.
Problem in creating a new workspace in an Eclipse RCP application.
When the RCP application is launched, a dialog is prompted to ask the workspace location.
When the location is given, then there is error saying "Could not launch the product because the specified workspace cannot be created.
The specified workspace directory is either invalid or read-only".
I have followed the code from IDEApplication.java from eclipse, but still I am facing same issue.
Application code:
#SuppressWarnings("restriction")
public class MyRcpApplication implements IApplication
{
private static final String METADATA_PROJECTS_PATH = "/.plugins/org.eclipse.core.resources/.projects";
private static final String METADATA_ROOT = ".metadata";
private static final String COMMAND_ARG = "--container";
private static final String SYSTEM_PROPERTY_EXIT_CODE = "eclipse.exitcode";
private static final String WORKSPACE_VERSION_KEY = "org.eclipse.core.runtime";
private static final String VERSION_FILENAME = "version.ini";
private static final String WORKSPACE_VERSION_VALUE = "1"; //$NON-NLS-1$
public static final String METADATA_FOLDER = ".metadata"; //$NON-NLS-1$
private Shell shell;
/*
* (non-Javadoc)
*
* #see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
*/
#Override
public Object start(final IApplicationContext context)
{
Display display = PlatformUI.createDisplay();
Shell shell = display.getActiveShell();
try
{
// for backward compatibility we need to clear the workspace before start also
cleanUpTheWorkSpace();
boolean instanceLocationCheck = checkInstanceLocation(shell, context.getArguments());
if (!instanceLocationCheck)
{
MessageDialog.openError(shell, IDEWorkbenchMessages.IDEApplication_workspaceInUseTitle,
"Could not launch the product because the associated workspace is currently in use by another My Application.");
return IApplication.EXIT_OK;
}
int returnCode = PlatformUI.createAndRunWorkbench(display, new MyApplicationWorkbenchAdvisor());
if (returnCode == PlatformUI.RETURN_RESTART)
{
// eclipse.exitcode system property may be set to re-launch
if (IApplication.EXIT_RELAUNCH.equals(Integer.getInteger(SYSTEM_PROPERTY_EXIT_CODE)))
{
return IApplication.EXIT_RELAUNCH;
}
return IApplication.EXIT_RESTART;
}
// if application return code is exit clean up the workspace
// cleanUpTheWorkSpace();
return IApplication.EXIT_OK;
}
finally
{
if (display != null)
{
display.dispose();
}
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc != null)
{
instanceLoc.release();
}
}
}
#SuppressWarnings("rawtypes")
private boolean checkInstanceLocation(final Shell shell, final Map arguments)
{
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc == null)
{
MessageDialog.openError(shell, "Workspace is Mandatory", "IDEs need a valid workspace.");
return false;
}
// -data "/valid/path", workspace already set
if (instanceLoc.isSet())
{
// make sure the meta data version is compatible (or the user has
// chosen to overwrite it).
try
{
// Used to check whether are we launching My application from development environment or not
if (isDevLaunchMode(arguments))
{
return true;
}
// Used to check instance location is locked or not
if (instanceLoc.isLocked())
{
return false;
}
// we failed to create the directory.
// Two possibilities:
// 1. directory is already in use
// 2. directory could not be created
File workspaceDirectory = new File(instanceLoc.getURL().getFile());
if (workspaceDirectory.exists())
{
if (isDevLaunchMode(arguments))
{
return true;
}
MessageDialog.openError(
shell,
"Workspace Cannot Be Locked",
"Could not launch the product because the associated workspace at '" + workspaceDirectory.getAbsolutePath()
+ "' is currently in use by another Eclipse application");
}
else
{
MessageDialog
.openError(
shell,
"Workspace Cannot Be Created",
"Could not launch the product because the specified workspace cannot be created. The specified workspace directory is either invalid or read-only.");
}
}
catch (IOException e)
{
MessageDialog.openError(shell, "Internal Error", e.getMessage());
}
}
else
{
try
{
// -data #noDefault or -data not specified, prompt and set
ChooseWorkspaceData launchData = new ChooseWorkspaceData(instanceLoc.getDefault());
boolean force = false;
while (true)
{
URL workspaceUrl = promptForWorkspace(shell, launchData, force);
if (workspaceUrl == null)
{
return false;
}
// if there is an error with the first selection, then force the
// dialog to open to give the user a chance to correct
force = true;
try
{
// the operation will fail if the url is not a valid
// instance data area, so other checking is unneeded
if (instanceLoc.set(workspaceUrl, false))
{
launchData.writePersistedData();
writeWorkspaceVersion(workspaceUrl);
return true;
}
}
catch (IllegalStateException e)
{
MessageDialog
.openError(
shell,
IDEWorkbenchMessages
.IDEApplication_workspaceCannotBeSetTitle,
IDEWorkbenchMessages
.IDEApplication_workspaceCannotBeSetMessage);
return false;
}
// by this point it has been determined that the workspace is
// already in use -- force the user to choose again
MessageDialog.openError(shell, IDEWorkbenchMessages
.IDEApplication_workspaceInUseTitle,
IDEWorkbenchMessages.
IDEApplication_workspaceInUseMessage);
}
}
catch (IllegalStateException | IOException e)
{
}
}
return true;
}
private static void writeWorkspaceVersion(final URL defaultValue)
{
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc.isReadOnly())
{
// MessageDialog.openError(shell,"Read-Only Dialog", "Location was read-only");
System.out.println("Instance Got Locked......");
}
if ((instanceLoc == null) || instanceLoc.isReadOnly())
{
return;
}
File versionFile = getVersionFile(instanceLoc.getURL(), true);
if (versionFile == null)
{
return;
}
OutputStream output = null;
try
{
String versionLine = WORKSPACE_VERSION_KEY + '=' + WORKSPACE_VERSION_VALUE;
output = new FileOutputStream(versionFile);
output.write(versionLine.getBytes("UTF-8")); //$NON-NLS-1$
}
catch (IOException e)
{
IDEWorkbenchPlugin.log("Could not write version file", //$NON-NLS-1$
StatusUtil.newStatus(IStatus.ERROR, e.getMessage(), e));
}
finally
{
try
{
if (output != null)
{
output.close();
}
}
catch (IOException e)
{
// do nothing
}
}
}
/*
* (non-Javadoc)
*
* #see org.eclipse.equinox.app.IApplication#stop()
*/
#Override
public void stop()
{
if (!PlatformUI.isWorkbenchRunning())
{
return;
}
final IWorkbench workbench = PlatformUI.getWorkbench();
final Display display = workbench.getDisplay();
display.syncExec(new Runnable()
{
#Override
public void run()
{
if (!display.isDisposed())
{
workbench.close();
}
}
});
}
private URL promptForWorkspace(final Shell shell, final ChooseWorkspaceData launchData, boolean force)
{
URL url = null;
do
{
new ChooseWorkspaceDialog(shell, launchData, false, force).prompt(force);
String instancePath = launchData.getSelection();
if (instancePath == null)
{
return null;
}
// the dialog is not forced on the first iteration, but is on every
// subsequent one -- if there was an error then the user needs to be
// allowed to
force = true;
// create the workspace if it does not already exist
File workspace = new File(instancePath);
if (!workspace.exists())
{
workspace.mkdir();
}
try
{
// Don't use File.toURL() since it adds a leading slash that Platform does not
// handle properly. See bug 54081 for more details.
String path = workspace.getAbsolutePath().replace(File.separatorChar, '/');
url = new URL("file", null, path); //$NON-NLS-1$
}
catch (MalformedURLException e)
{
MessageDialog
.openError(
shell,
IDEWorkbenchMessages
.IDEApplication_workspaceInvalidTitle,
IDEWorkbenchMessages
.IDEApplication_workspaceInvalidMessage);
continue;
}
}
while (!checkValidWorkspace(shell, url));
return url;
}
private boolean checkValidWorkspace(final Shell shell, final URL url)
{
String version = readWorkspaceVersion(url);
// if the version could not be read, then there is not any existing
// workspace data to trample, e.g., perhaps its a new directory that
// is just starting to be used as a workspace
if (version == null)
{
return true;
}
final int ide_version = Integer.parseInt(WORKSPACE_VERSION_VALUE);
int workspace_version = Integer.parseInt(version);
// equality test is required since any version difference (newer
// or older) may result in data being trampled
if (workspace_version == ide_version)
{
return true;
}
// At this point workspace has been detected to be from a version
// other than the current ide version -- find out if the user wants
// to use it anyhow.
String title = "My App Titile"; //$NON-NLS-1$
String message = "My App Message";
MessageBox mbox = new MessageBox(shell, SWT.OK | SWT.CANCEL
| SWT.ICON_WARNING | SWT.APPLICATION_MODAL);
mbox.setText(title);
mbox.setMessage(message);
return mbox.open() == SWT.OK;
}
private static String readWorkspaceVersion(final URL workspace)
{
File versionFile = getVersionFile(workspace, false);
if ((versionFile == null) || !versionFile.exists())
{
return null;
}
try
{
// Although the version file is not spec'ed to be a Java properties
// file, it happens to follow the same format currently, so using
// Properties to read it is convenient.
Properties props = new Properties();
FileInputStream is = new FileInputStream(versionFile);
try
{
props.load(is);
}
finally
{
is.close();
}
return props.getProperty(WORKSPACE_VERSION_KEY);
}
catch (IOException e)
{
IDEWorkbenchPlugin.log("Could not read version file", new Status( //$NON-NLS-1$
IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH,
IStatus.ERROR,
e.getMessage() == null ? "" : e.getMessage(), //$NON-NLS-1$,
e));
return null;
}
}
private static File getVersionFile(final URL workspaceUrl, final boolean create)
{
if (workspaceUrl == null)
{
return null;
}
try
{
// make sure the directory exists
File metaDir = new File(workspaceUrl.getPath(), METADATA_FOLDER);
if (!metaDir.exists() && (!create || !metaDir.mkdir()))
{
return null;
}
// make sure the file exists
File versionFile = new File(metaDir, VERSION_FILENAME);
if (!versionFile.exists()
&& (!create || !versionFile.createNewFile()))
{
return null;
}
return versionFile;
}
catch (IOException e)
{
// cannot log because instance area has not been set
return null;
}
}
#SuppressWarnings("rawtypes")
private static boolean isDevLaunchMode(final Map args)
{
// see org.eclipse.pde.internal.core.PluginPathFinder.isDevLaunchMode()
if (Boolean.getBoolean("eclipse.pde.launch"))
{
return true;
}
return args.containsKey("-pdelaunch"); //$NON-NLS-1$
}
/**
* Deletes all the available projects in the workspace
*/
private void cleanUpTheWorkSpace()
{
// this will be the
String[] commands = Platform.getCommandLineArgs();
if (commands != null)
{
List<String> args = Arrays.asList(commands);
if (args.contains(COMMAND_ARG))
{
// if project is in the root delete it.. it will delete associated metadata
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
if (projects != null)
{
for (IProject project : projects)
{
try
{
project.delete(true, new NullProgressMonitor());
}
catch (CoreException e)
{
// msgHandler.post(MsgSeverity.ERROR, "Unable to clear the workspace");
}
}
}
// if project is not in the root but if its in the workspace delete the metadata too
File[] workSpaceFiles = Platform.getLocation().toFile().listFiles();
for (File file : workSpaceFiles)
{
if (METADATA_ROOT.equals(file.getName()))
{
File projectMeta = new File(file.getPath() + METADATA_PROJECTS_PATH);
if ((projectMeta != null) && projectMeta.exists())
{
File[] children = projectMeta.listFiles();
for (File child : children)
{
FileUtils.deleteQuietly(child);
}
}
}
/*
* else { FileUtils.deleteQuietly(file); }
*/
}
}
}
}
}
Try run Eclipse as administrator.
Your code is just calling
if (instanceLoc.isLocked())
{
return false;
}
to check if the workspace is locked, but is doing nothing to make the workspace locked so this will always fall through to the error code.
IDEApplication does this:
if (instanceLoc.lock()) {
writeWorkspaceVersion();
return null;
}
you need to do something similar.
I want to close a thread by calling a method after the jdbc Driver has been deregister.
public class CleanupContextListener implements ServletContextListener{
boolean driverDeregisterFlag = false;
public void contextInitialized(ServletContextEvent servletContextEvent) {
//To change body of implemented methods use File | Settings | File Templates.
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
Enumeration<Driver> drivers = DriverManager.getDrivers();
while(drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
ClassLoader driverClassLoader = driver.getClass().getClassLoader();
ClassLoader thisClassLoader = this.getClass().getClassLoader();
if (driverClassLoader != null && thisClassLoader != null && driverClassLoader.equals(thisClassLoader)) {
try {
DriverManager.deregisterDriver(driver);
driverDeregisterFlag = true;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
if (driverDeregisterFlag) {
ConfigManager.stopCurrentThread();
}
}
}
As you can see I'm trying to call the ConfigManager.stopCurrentThread() and stop the current Thread.
ConfigManager is a class that implements Runnable.
stopCurrentThread(), is defined as an empty method in ConfigManager.
I want to put some code inside stopCurrentThread() and close the thread from ConfigManager.
How can I do that?
This is fragment of my code which is solving similar problem. Tested on c3p0 pool + tomcat 8, but you will be probably able to modify it to you needs.
/**
* Destroying application context. We need to safely stop exporting thread
* and do cleanup.
*
* #param arg0
* reason for cleanup
*/
#Override
public void contextDestroyed(#NotNull ServletContextEvent arg0) {
// Safely stop exporting service and shut down the application context
super.contextDestroyed(arg0);
// Close all JDBC connections
C3P0Registry.getNumPooledDataSources();
Iterator<?> it = C3P0Registry.getPooledDataSources().iterator();
while (it.hasNext()) {
try {
PooledDataSource dataSource = (PooledDataSource) it.next();
dataSource.close();
} catch (Exception e) {
log.error("Error when closing connections ...", e);
}
}
// This manually unregisters JDBC drivers, which prevents Tomcat 7 from
// complaining about memory leaks with this class
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
log.info(String.format("Unregistering jdbc driver: %s", driver));
} catch (SQLException e) {
log.error(
String.format("Error deregistering driver %s", driver),
e);
}
}
// Waiting for daemon close() c3p0 jdbc pool thread
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread th : threadSet) {
if (th.isDaemon()) {
try {
if (th.getName().equals(
"Resource Destroyer in BasicResourcePool.close()")) {
th.join();
}
} catch (Exception ex) {
log.info("Shutdown waiting was interrupted ...");
}
}
}
// Clear all thread local variables, this prevents Tomcat 7 from
// complaining about memory leaks
immolate();
}
/**
* Cleanup function which cleans all thread local variables. Using thread
* local variables is not a good practice but unfortunately some libraries
* are still using them. We need to clean them up to prevent memory leaks.
*
* #return number of Thread local variables
*/
private int immolate() {
int count = 0;
try {
final Field threadLocalsField = Thread.class
.getDeclaredField("threadLocals");
threadLocalsField.setAccessible(true);
final Field inheritableThreadLocalsField = Thread.class
.getDeclaredField("inheritableThreadLocals");
inheritableThreadLocalsField.setAccessible(true);
for (final Thread thread : Thread.getAllStackTraces().keySet()) {
count += clear(threadLocalsField.get(thread));
count += clear(inheritableThreadLocalsField.get(thread));
}
log.info("Immolated " + count + " values in ThreadLocals");
} catch (Exception e) {
log.error("ThreadLocalImmolater.immolate()", e);
}
return count;
}
/**
* Cleaner for thread local map.
*
* #param threadLocalMap
* thread local map to clean or null
* #return number of cleaned objects
* #throws Exception
* in case of error
*/
private int clear(#NotNull final Object threadLocalMap) throws Exception {
if (threadLocalMap == null) {
return 0;
}
int count = 0;
final Field tableField = threadLocalMap.getClass().getDeclaredField(
"table");
tableField.setAccessible(true);
final Object table = tableField.get(threadLocalMap);
for (int i = 0, length = Array.getLength(table); i < length; ++i) {
final Object entry = Array.get(table, i);
if (entry != null) {
final Object threadLocal = ((WeakReference<?>) entry).get();
if (threadLocal != null) {
log(i, threadLocal);
Array.set(table, i, null);
++count;
}
}
}
return count;
}
I am writing a service that calls a few external services. I am using futures to represent the result of all those external service calls. I collapse all the futures to a single future using Futures.successfulAsList() method provided by Guava library.
Here is my code
List<ListenableFuture<List<T>>> futureList = new ArrayList<>();
for(int id: shardIds) {
ListeningExecutorService service =
(ListeningExecutorService) _shardMgr.getExecutorService(id);
SelectTask task = new SelectTask(_shardMgr.getReadHandle(id), sql, mapper);
ListenableFuture<List<T>> future = service.submit(task);
//Add Callback
Futures.addCallback(future, new ErrorCallBack(task),
Executors.newFixedThreadPool(1));
futureList.add(future);
}
ListenableFuture<List<List<T>>> combinedFuture =
Futures.successfulAsList(futureList);
int timeout = _dbTimeout.get();
List<T> selectResult = new ArrayList<T>();
try {
List<List<T>> result = combinedFuture.get(timeout, TimeUnit.MILLISECONDS);
for(List<T> sublist: result) {
for(T t : sublist) {
//TODO: Do we want to put a cap on how many results we return here?
//I think we should
selectResult.add(t);
}
}
}
catch(Exception ex) {
log.error("******************* Exception in parallelSelect ",ex);
throw new RuntimeException("Error in parallelSelect");
}
When one of my future ( external service call ) fails ErrorCallBack's onFailure() is called, But i still get past of combinedFuture.get(timeout, TimeUnit.MILLISECONDS); and i get NullPointerException in line for(T t : sublist) ... while iterating over the results.
I expect that when one external service call fails, i should not get past combinedFuture.get()
Am i doing something wrong ? I even tried to throw Exception from ErrorCallBack's onFailure method.
Here is ErrorCallBack's implementation
private class ErrorCallBack<T> implements FutureCallback<List<T>> {
private final SelectTask _task;
public ErrorCallBack(SelectTask task) {
_task = task;
}
#Override
public void onFailure(Throwable t) {
log.error("ErrorCallBack:onFailure(). Enter");
DBErrorType type = DBErrorType.UNKNOWN;
try {
log.error("ErrorCallBack:onFailure(). Exception ",t);
if(t instanceof InterruptedException || t instanceof CancellationException) {
type = DBErrorType.UNKNOWN;
} else if ( t instanceof SQLException || t.getCause() instanceof SQLException) {
type = DBErrorType.SQL_SYNTAX_ERROR;
} else if ( t instanceof MySQLSyntaxErrorException || t.getCause() instanceof MySQLSyntaxErrorException) {
type = DBErrorType.SQL_SYNTAX_ERROR;
} else if ( t instanceof ExecutionException) {
type = DBErrorType.SQL_SYNTAX_ERROR;
} else if (t instanceof TimeoutException) {
type = DBErrorType.NETWORK_ERROR;
} else {
type = DBErrorType.UNKNOWN;
}
ShardHandle handle = _task.getShardHandle();
_shardMgr.reportException(handle, type);
DBException exception = new DBException(handle.getShardInfo(), type, ErrorSeverity.CRITICAL, t);
_alertModule.handleAlert(exception.getAlertContext());
} catch( Exception ex) {
}
}
#Override
public void onSuccess(List<T> result) {}
}
I expect that when one external service call fails, i should not get past combinedFuture.get()
Well, no, since you're calling Futures.succcessfulAsList() which, as its name implies, returns the results of the successful Futures (and null for those that failed). For the behaviour you want, you should call Futures.allAsList() which gives you a Future that fails if any of its components fail.
Since you're not checking for nulls in the results, you get the NPE.
I'm having problem when taking a picture using VideoControl.getSnapshot() method. It always throw the exception: getSnapshot not Supported. I'm using JRE 5.0.0 with Eclipse and BlackBerry® Java® SDK 5.0 Plugin.
What I do first is to list the encoding supported by Blackberry SmartPhone selected (bold 9700) with the command System.getProperty("video.snapshot.encodings") and select one encoding from the list and pass it as the getSnapshot argument.
I've tested on several Blackberry and the same exception is thrown.
Part of the code:
mPlayer = Manager.createPlayer("capture://video?encoding=video/3gpp");
mPlayer.realize();
mPlayer = Manager.createPlayer("capture://video?encoding=video/3gpp");
mPlayer.start();
videoControl = (VideoControl)mPlayer.getControl("VideoControl");
Field cameraView = (Field) videoControl.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field");
Thread.sleep(1000);
UiApplication.getUiApplication().pushScreen(new TempScreen(cameraView));
byte[] snapShot = videoControl.getSnapshot("encoding=jpeg&width=480&height=360&quality=superfine");
Bitmap image = Bitmap.createBitmapFromBytes(snapShot, 0, snapShot.length, 1);
UiApplication.getUiApplication().pushScreen(new TempScreen(image));
}catch (MediaException e){
UiApplication.getUiApplication().pushScreen(new TempScreen("Exception: " + e.getMessage())); }
catch (IOException e){
UiApplication.getUiApplication().pushScreen(new TempScreen("IO Exception: " + e.getMessage()));
}
catch (InterruptedException e){UiApplication.getUiApplication().pushScreen(new TempScreen("Interrupted Exception: "+ e.getMessage()));}
Not sure is my answer is actual after more than a half of year, but may be it will be useful.
You may try to use Thread.sleep(1000); before getSnapshot() call.
The problem may be related with that fact: "viewfinder must actually be visible on the screen prior to calling getSnapShot()."
So if you call getSnapshot immediately after UiApplication.getUiApplication().pushScreen(new TempScreen(cameraView));
the camera isn't prepared for the next shot.
Also are you really sure that getSnapshot() API is supported exactly on your device? Some manufacturers may not support it, despite the API defines this method. Did you run System.getProperty("video.snapshot.encodings") exactly on the same device where you test getSnapshot()?
Player _p;
VideoControl _vc ;
RecordControl _rc ;
String PATH;
FileConnection fileconn;
Object canvas= new Object();
public static boolean SdcardAvailabulity() {
String root = null;
Enumeration e = FileSystemRegistry.listRoots();
while (e.hasMoreElements()) {
root = (String) e.nextElement();
if( root.equalsIgnoreCase("sdcard/") ) {
return true;
}else if( root.equalsIgnoreCase("store/") ) {
return false;
}
}
class MySDListener implements FileSystemListener {
public void rootChanged(int state, String rootName) {
if( state == ROOT_ADDED ) {
if( rootName.equalsIgnoreCase("sdcard/") ) {
}
} else if( state == ROOT_REMOVED ) {
}
}
}
return true;
}
protected boolean invokeAction(int action){
boolean handled = super.invokeAction(action);
if(SdcardAvailabulity()){
PATH = System.getProperty("fileconn.dir.memorycard.videos")+"Video_"+System.currentTimeMillis()+".3gpp";//here "str" having the current Date and Time;
} else {
PATH = System.getProperty("fileconn.dir.videos")+"Video_"+System.currentTimeMillis()+".3gpp";
}
if(!handled){
if(action == ACTION_INVOKE){
try{
if(_p!=null)
_p.close();
}catch(Exception e){
}
}
}
return handled;
}
public MyScreen(){
setTitle("Video recording demo");
ButtonField AddPhoto = new ButtonField("push",ButtonField.FOCUSABLE | ButtonField.FIELD_HCENTER | ButtonField.FIELD_VCENTER | DrawStyle.HCENTER | ButtonField.NEVER_DIRTY | Field.USE_ALL_WIDTH);
FieldChangeListener PhotoListener = new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
ButtonField Button = (ButtonField) field;
if (Button.getLabel().equals("push")){
}
}
};
AddPhoto.setChangeListener(PhotoListener);
add(AddPhoto);
}
}