Here below are the exception logs:
java.lang.ClassCastException: char[] cannot be cast to android.app.SharedPreferencesImpl
at android.app.ContextImpl.getSharedPreferences(ContextImpl.java:358)
at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:171)
at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:171)
at com.android.internal.telephony.cat.CatService.saveCmdToPreference(CatService.java:2632)
at com.android.internal.telephony.cat.CatService.handleDBHandler(CatService.java:2079)
at com.android.internal.telephony.cat.CatService.handleMessage(CatService.java:1841)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Loo|debug info:dalvik.system.VMStack.getThreadStackTrace(Native Method)|java.lang.Thread.getStackTrace(Thread.java:580)|java.lang.Thread.getAllStackTraces(Thread.java:522)|com.letv.bsp.crashhandler.utils.LogUtils.trace(LogUtils.java:86)|com.letv.bsp.crashhandler.CrashHandleService.reportException(CrashHandleService.java:915)|com.letv.bsp.crashhandler.CrashHandleService.onStartCommand(CrashHandleService.java:663)|android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3291)|android.app.ActivityThread.-wrap18(ActivityThread.java)|android.app.ActivityThread$H.handleMessage(ActivityThread.java:1674)|android.os.Handler.dispatchMessage(Handler.java:111)|android.os.Looper.loop(Looper.java:207)|android.app.ActivityThread.main(ActivityThread.java:5905)|java.lang.reflect.Method.invoke(Native Method)|com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)|com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)|, blk: false printBlacklist the current black list :
And here below are the codes exception throws at android.app.ContextImpl.getSharedPreferences
#Override
public SharedPreferences getSharedPreferences(String name, int mode) {
SharedPreferencesImpl sp;
synchronized (ContextImpl.class) {
if (sSharedPrefs == null) {
sSharedPrefs = new ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>>();
}
final String packageName = getPackageName();
ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
if (packagePrefs == null) {
packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
sSharedPrefs.put(packageName, packagePrefs);
}
// At least one application in the world actually passes in a null
// name. This happened to work because when we generated the file name
// we would stringify it to "null.xml". Nice.
if (mPackageInfo.getApplicationInfo().targetSdkVersion <
Build.VERSION_CODES.KITKAT) {
if (name == null) {
name = "null";
} // here is the line 358
}
sp = packagePrefs.get(name);
if (sp == null) {
File prefsFile = getSharedPrefsFile(name);
sp = new SharedPreferencesImpl(prefsFile, mode);
packagePrefs.put(name, sp);
return sp;
}
}
if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
// If somebody else (some other process) changed the prefs
// file behind our back, we reload it. This has been the
// historical (if undocumented) behavior.
sp.startReloadIfChangedUnexpectedly();
}
return sp;
}
Let's suppose the log information is correct, and it should be correct almost.
My first question is: what does it mean by saying that throws cast exception at line 358 at ContextImpl.java file? There is only a right brace there.
I guess the statement below line 358 is the root case of the exception
sp = packagePrefs.get(name);
because sp is declare as SharedPreferencesImpl, and it should have a cast operation when the get method return and assignment, if the value return is a char[], then the cast exception should throw, this explanation is very reasonable. But the value in packagePrefs has parameterized as SharedPreferencesImpl once declare at
packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
Therefore, it should have no chance to put a value type of char[] into packagePrefs. Then, I am confused again, where is the code occur this exception and why.
There is another similar problem, the log is:
java.lang.ClassCastException: char[] cannot be cast to com.android.internal.util.StateMachine$LogRec
at com.android.internal.util.StateMachine$LogRecords.add(StateMachine.java:665)
at com.android.internal.util.StateMachine$SmHandler.performTransitions(StateMachine.java:830)
at com.android.internal.util.StateMachine$SmHandler.handleMessage(StateMachine.java:801)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.os.HandlerThread.run(HandlerThread.java:61)
And the corresponding codes is at com.android.internal.util.StateMachine.LogRecords:
private Vector<LogRec> mLogRecVector = new Vector<LogRec>();
synchronized void add(StateMachine sm, Message msg, String messageInfo, IState state,
IState orgState, IState transToState) {
mCount += 1;
if (mLogRecVector.size() < mMaxSize) {
mLogRecVector.add(new LogRec(sm, msg, messageInfo, state, orgState, transToState));
} else {
LogRec pmi = mLogRecVector.get(mOldestIndex);
mOldestIndex += 1;
if (mOldestIndex >= mMaxSize) {
mOldestIndex = 0;
}
pmi.update(sm, msg, messageInfo, state, orgState, transToState);
}
}
It both seems to be a problem about generic. Hope help from experts here and thanks so much in advance.
To the first issue (that the line number doesn't correspond to the error) my guess is you added three lines (perhaps the name = "null" conditional) since last compiling. Any time you see stack traces that don't seem to line-up that's a strong hint that your source and your binary are out of sync.
For the second issue that we shouldn't see a ClassCastException because packagePrefs and mLogRecVector are generic, I'd agree this seems impossible if your code snippets compile (you might run into issues if sSharedPrefs were a raw type, but I'm assuming that's not the case). My first theory would be that you need to re-build (going off of the hint that the stack trace doesn't line up with your source code).
If a full rebuild doesn't work I'd have to assume this is an Android-specific issue (perhaps you're using ProGuard?). Are you able to replicate this in OracleJDK or OpenJDK? If you can create an MCVE that we can replicate the issue with it would help get to the bottom of this.
Related
Giving an example, lets say we have a code like the one below:
String phone = currentCustomer.getMainAddress().getContactInformation().getLandline()
As we know there is no elvis operator in Java and catching NPE like this:
String phone = null;
try {
phone = currentCustomer.getMainAddress().getContactInformation().getLandline()
} catch (NullPointerException npe) {}
Is not something anyone would advise. Using Java 8 Optional is one solution but the code is far from clear to read -> something along these lines:
String phone = Optional.ofNullable(currentCustomer).flatMap(Customer::getMainAddress)
.flatMap(Address::getContactInformation)
.map(ContactInfo::getLandline)
.orElse(null);
So, is there any other robust solution that does not sacrifice readability?
Edit: There were some good ideas already below, but let's assume the model is either auto generated (not convenient to alter each time) or inside a third party jar that would need to be rebuild from source to be modified.
The "heart" of the problem
This pattern currentCustomer.getMainAddress().getContactInformation().getLandline() is called TrainWreck and should be avoided. Had you done that - not only you'd have better encapsulation and less coupled code, as a "side-effect" you wouldn't have to deal with this problem you're currently facing.
How to do it?
Simple, the class of currentCustomer should expose a new method: getPhoneNumber() this way the user can call: currentCustomer.getPhoneNumber() without worrying about the implementation details (which are exposed by the train-wreck).
Does it completely solve my problem?
No. But now you can use Java 8 optional to tweak the last step. Unlike the example in the question, Optionals are used to return from a method when the returned value might be null, lets see how it can be implemented (inside class Customer):
Optional<String> getPhoneNumber() {
Optional<String> phone = Optional.empty();
try {
phone = Optional.of(mainAddress.getContactInformation().getLandline());
} catch (NullPointerException npe) {
// you might want to do something here:
// print to log, report error metric etc
}
return phone;
}
Per Nick's comment below, ideally, the method getLandline() would return an Optional<String>, this way we can skip the bad practice of swallowing up exceptions (and also raising them when we can avoid it), this would also make our code cleaner as well as more concise:
Optional<String> getPhoneNumber() {
Optional<String> phone = mainAddress.getContactInformation().getLandline();
return phone;
}
String s = null;
System.out.println(s == null);
or
String s = null;
if(s == null)System.out.println("Bad Input, please try again");
If your question was with the object being null, you should have made that clear in your question...
PhoneObject po = null;
if(po==null) System.out.println("This object is null");
If your problem is with checking whether all the parts of the line are null, then you should have also made that clear...
if(phone == null) return -1;
Customer c = phone.currentCustomer();
if(c == null)return -1;
MainAddress ma = c.getMainAddress();
if(ma == null) return -1;
ContactInfo ci = ma.getContactInformation();
if(ci == null)return -1;
LandLine ll = ci.getLandline();
if(ll == null)return -1;
else return ll.toNumber()//or whatever method
Honestly, code that's well written shouldn't have this many opportunities to return null.
For some reason, when I compile this simple code, an error pops up. (If I had 10 rep I would post it) It basically says (File Directory) uses unchecked or unsafe operations. Recompile with -Xlint: unchecked for details. I experimented a little and it seems if I take away the Bin.add() the error goes away. Can someone explain what I should do?
import java.util.ArrayList;
public class Summoned_Bin
{
ArrayList Bin = new ArrayList();
Summoned_Bin()
{
}
void addToBin()
{
Summon summoned = new Summon();
int index = 0;
while (Bin.get(index) != null)
{
index++;
}
Bin.add(index , summoned ); //Without this it runs fine
}
}
I think it wants you to type the list List<Summon> Bin = new ArrayList<Summon>();
Three things to note:
Declare the type as List<Summon> instead of ArrayList<Summon> its best practice to use the interface, which will allow you to change the type at a later date.
The Summoned_Bin class should follow Java naming standards, so SummonedBin should be the name.
Also the name of the SummonedBin object should follow Java naming standards, use bin instead of Bin.
Revised Class
public class SummonedBin {
List<Summon> bin = new ArrayList<Summon>();
SummonedBin() {
}
void addToBin() {
Summon summoned = new Summon();
int index = 0;
while (bin.get(index) != null) {
index++;
}
bin.add(index, summoned);
}
}
It's not error, it's only warning.
You want to do explicit type definition:
ArrayList<Summon> Bin = new ArrayList<Summon>();
I think I have a simple mistake in my code but I can't find it.
I have a list of Objects (type of an entity) and I want to read the content of the objects in the list.
In my opinion something like:
object.get(1).getTitle();
List<HtMeldungen> meldungen = q.getResultList();
List<MeldungsBean> meldungsliste = new ArrayList();
MeldungsBean mb = null;
HtMeldungen tempMeldungen = null;
int i = 0;
int k = meldungen.size() - 1;
for (i = 0; i < k; i++) {
mb = new MeldungsBean();
tempMeldungen = (HtMeldungen) meldungen.get(i);
mb.setTitel(tempMeldungen.getTitle());
mb.setAutor(tempMeldungen.getAutor());
mb.setMeldungstext(tempMeldungen.getText());
meldungsliste.add(mb);
}
My list named meldungen is filled with objects of type HtMeldungen.
I get the error:
DBEntities.classic.HtMeldungen cannot be cast to DBEntities.classic.HtMeldungen
Can anyone help me?
Are you sure q.getResultList() gets a list with instances of HtMeldungen?
If not, then the line
List<HtMeldungen> meldungen = q.getResultList();
is - depending of your compiler switches - syntactically correct, but the list can contain instances of a different class, and later in the line
tempMeldungen = (HtMeldungen) meldungen.get(i);
you get your exception, because that what the compiler thinks it must be instance of HtMeldungen in fact isn't.
Try the code
if (meldungen.get(i) instanceof HtMeldungen) {
tempMeldungen = (HtMeldungen) meldungen.get(i);
} else {
throw new RuntimeException("Got instance of class " + meldungen.get(i).getClass());
}
then you get an understandable error if your assumption should have been wrong.
I'll get the error: DBEntities.classic.HtMeldungen cannot be cast to DBEntities.classic.HtMeldungen
Since the error message indicates that an object of HtMeldungen cannot be cast to HtMeldungen (which seems contradictory), I would think that you might have this class loading twice in your build. Please check to see if your build path is putting the same jar in the build twice. That is what usually causes this error.
For some reason I am receiving errors in the code below and I can't see why, can you spot any?
public void delTask_mouseClicked(MouseEvent e)
{
if(delTask.isEnabled() == false) {
int numTasks = taskTable.getRowCount();
Object[] currentTasks;
currentTasks = new Object[numTasks];
for (int i = 0; i < numTasks ; i++){
Object tasks = taskTable.getModel().getValueAt(i, 1);
currentTasks[i] = tasks;
}
System.out.println(currentTasks);
}
}
Thanks for the help, it's really appreciated.
There massive block of errors I am getting is below:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at projecttaskmanagement.ProjectGUI.delTask_mouseClicked(ProjectGUI.java:233)
at projecttaskmanagement.ProjectGUI$2.mouseClicked(ProjectGUI.java:109)
at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:212)
at java.awt.Component.processMouseEvent(Component.java:5520)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3135)
at java.awt.Component.processEvent(Component.java:5282)
at java.awt.Container.processEvent(Container.java:1966)
at java.awt.Component.dispatchEventImpl(Component.java:3984)
at java.awt.Container.dispatchEventImpl(Container.java:2024)
at java.awt.Component.dispatchEvent(Component.java:3819)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3901)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)
at java.awt.Container.dispatchEventImpl(Container.java:2010)
at java.awt.Window.dispatchEventImpl(Window.java:1791)
at java.awt.Component.dispatchEvent(Component.java:3819)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
CODE AT LINE 233:
int numTasks = taskTable.getRowCount();
TASK TABLE IS DEFINED BELOW:
String[] taskcolumnNames = {"ID #",
"Name",
"Description",
"Start Date",
"End Date",
"Staff",
"Completed"};
Object[][] taskdata = {
{new Integer(1), "Requirements Analysis",
"Analysing the requirements",
"01/09/2011", "15/10/2011",
"Bob", new Boolean(true)},
{new Integer(2), "System Design",
"Designing the System",
"15/09/2011", "15/10/2011",
"Alice", new Boolean(true)},
{new Integer(3), "Code (A)",
"Part 'A' of coding",
"01/10/2011", "15/11/2011",
"David", new Boolean(true)},
};
JTable taskTable = new JTable(taskdata, taskcolumnNames);
While we're waiting for you to post the actual errors you're getting (a), please take a moment to NEVER do this:
if (delTask.isEnabled() == false)
A much better form is the simpler-to-read:
if (! delTask.isEnabled())
We now return you to your scheduled programming, pending your update.
Dum de dum de dum ...
Now, based on your update, the following part of the stackdump:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at projecttaskmanagement.ProjectGUI.delTask_mouseClicked(ProjectGUI.java:233)
indicates where the problem lies. Find out which of those lines of yours in line number 233 and there you have it. The thing that you're trying to deference on that line is in fact a null reference.
Based on the snippet, it'll probably be one of the following lines:
public void delTask_mouseClicked(MouseEvent e)
{
if(delTask.isEnabled() == false) { // <--
int numTasks = taskTable.getRowCount(); // <--
Object[] currentTasks;
currentTasks = new Object[numTasks];
for (int i = 0; i < numTasks ; i++){
Object tasks = taskTable.getModel().getValueAt(i, 1); // <--
currentTasks[i] = tasks;
}
System.out.println(currentTasks);
}
}
The first will be because delTask itself is null, the second if taskTable is null.
The third will be if taskTable itself is valid but the value returned from its getModel() method is null.
So, it appears that your taskTable is null. As to why this is so, that's unknowable based on the current information. What you will need to do is examine all the places it's set to a valid value and ensure that this happens before you (or more likely, AWT under the control of your user) call this method.
And of course, make sure it's not set back to NULL at some point after creation.
If you can't guarantee that, you'll probably need to change:
if (delTask.isEnabled() == false)
into something like:
if ((! delTask.isEnabled()) && (taskTable != NULL))
but my preference would be to fix the root cause of the problem rather than applying this band-aid.
Your code that creates the JTable seems okay (syntactically) but there's the slight mystery of where that's done. Is it created in a manner that it's usable from where you're trying to use it.
For example, if that code that creates it is within the constructor, that particular taskTable would be local to said constructor (and destroyed on exit), not usable from elsewhere. In that case, it needs to be made an object-level variable so that other methods can get to it.
You can see that effect in the following program:
public class testprog {
public Object thingOne;
public Object thingTwo;
public void someFunction() {
thingOne = new Object();
Object thingTwo = new Object();
}
public void debug() {
if (thingOne == null)
System.out.println ("thingOne is NULL");
else
System.out.println ("thingOne is valid");
if (thingTwo == null)
System.out.println ("thingTwo is NULL");
else
System.out.println ("thingTwo is valid");
}
public static void main(String args[]) {
testprog tp = new testprog();
tp.someFunction();
tp.debug();
}
}
This outputs:
thingOne is valid
thingTwo is NULL
because thje thingTwo set up in someFunction() is a local version and does not in any way set up the object-level thingTwo - the object level one remains as null and, if you try to dereference it, you'll see the same problem you're having.
(a) The best problems reports come with a small, complete code snippet exhibiting the problem, the expected behaviour, and the actual behaviour.
If we post that sample of yours into a naked Eclipse Java program, it's very much not complete. MouseEvent, delTask and taskTable have no definitions and, without that information, it's a little hard to debug.
In addition, Eclipse (for syntax errors) and Java itself (for runtime errors) are perfectly able to tell you in great detail what your problems are, and you should read what it's telling you. You should also communicate that information to us if you want help :-)
Which line is line 233 of ProjectGUI.java? At least one of the following is null:
delTask
taskTable
taskTable.getModel()
Figure out which of those falls on line 233 (per your error report), and you've figured out where the problem lies. We'll need to see more code to determine why the variable does not have the expected value.
Usually, the code block works perfect. On very rare occasions though, the "new ArrayList" throws an Exeption my.namespace.CacheEntry cannot be stored in an array of type java.lang.Object[].
Checking Google, someone else seemed to get this exception on an Acer A500 with 3.1 (which is the device I got it, too). I don't see any hit for this in generic Java or whatever, so may be some very very Honeycomb special case or even a VM bug?
private long expireCache(HashMap<String, CacheEntry> map) {
long count = 0;
// next line will sometimes throw the exception:
ArrayList<CacheEntry> entries = new ArrayList<CacheEntry>(map.values());
Collections.sort(entries);
The CacheEntry class is quite regular, too:
final class CacheEntry implements Comparable<CacheEntry> {
public File file;
public Long time;
CacheEntry(File cacheFile) {
// retreive the lastModified only once, don't do heavy I/O for sorting,
// keep it desynced from filesystem so nothing bad happens when the
// file gets changed while sorting:
file = cacheFile;
time = cacheFile.lastModified();
}
// "touch" the cached last modified time
public void touch() {
time = System.currentTimeMillis();
}
// return the long comparable of last modified time
public int compareTo(CacheEntry c) {
return time.compareTo(c.time);
}
}
I don't see anything wrong with this code. Anyone?
may be some very very Honeycomb special case or even a VM bug?
Yes, looks like it, because according to Java semantics, there isn't anything that "cannot be stored in an array of type java.lang.Object[]" - except primitives, but those can't be values in a HashMap