I am trying to implement Ignite 3rd party persistence with SQL Server. I used the Web Console to generate the java model and I am able to execute the generated utility and configuration files without any issue (LoadCaches or ServerNodeCodeStartup, with config from ServerConfigurationFactory) -- the cache load call executes without any problem.
public TestPersistentStore() throws Exception {
try (Ignite ignite = Ignition.start(ServerConfigurationFactory.createConfiguration())) {
// Auto-close cache at the end of the example.
try (IgniteCache<Integer, Customer> cache = ignite.cache("CustomerCache")) {
// Make initial cache loading from persistent store. This is a
// distributed operation and will call CacheStore.loadCache(...)
// method on all nodes in topology.
loadCache(cache);
// Start transaction and execute several cache operations with
// read/write-through to persistent store.
executeTransaction(cache);
} catch (Exception e) {
e.printStackTrace();
} finally {
// Distributed cache could be removed from cluster only by #destroyCache() call.
ignite.destroyCache("CustomerCache");
}
} catch (Exception e) {
e.printStackTrace();
}
}
Content of executeTransaction:
private static void executeTransaction(IgniteCache<Integer, Customer> cache) {
int id = 1;
try (Transaction tx = Ignition.ignite("acmecorp").transactions().txStart()) {
Customer val = cache.get(id);
System.out.println("Read value: " + val);
val = cache.getAndPut(id, new Customer(id, "Isaac", "Newton", "Ixelles"));
System.out.println("Overwrote old value: " + val);
val = cache.get(id);
System.out.println("Read value: " + val);
tx.commit();
}
System.out.println("Read value after commit: " + cache.get(id));
}
(many of these lines of code were copied from CacheJdbcStoreExample)
Result of execution:
[22:53:35] Topology snapshot [ver=1, servers=1, clients=0, CPUs=4, heap=3.5GB]
>>> Loaded 10 keys with backups in 450ms.
Read value: Customer [firstName=Isaac, lastName=Newton, address=Ixelles]
Overwrote old value: Customer [firstName=Isaac, lastName=Newton, address=Ixelles]
Read value: Customer [firstName=Isaac, lastName=Newton, address=Ixelles]
Read value after commit: Customer [firstName=Isaac, lastName=Newton, address=Ixelles]
Read value skipping store (expecting null): null
Read value with store lookup (expecting NOT null): Customer [firstName=Isaac, lastName=Newton, address=Ixelles]
Read value skipping store (expecting NOT null): Customer [firstName=Isaac, lastName=Newton, address=Ixelles]
[22:53:36] Ignite node stopped OK [name=acmecorp, uptime=00:00:00:638]
So this works for the Customer table/cache. I want to use the same code but use another table/cache (Item), as follows:
TestPersistentStore2
public TestPersistentStore2() throws Exception {
try (Ignite ignite = Ignition.start(ServerConfigurationFactory.createConfiguration())) {
// Auto-close cache at the end of the example.
try (IgniteCache<Integer, Item> cache = ignite.cache("ItemCache")) {
// Make initial cache loading from persistent store. This is a
// distributed operation and will call CacheStore.loadCache(...)
// method on all nodes in topology.
loadCache(cache);
// Start transaction and execute several cache operations with
// read/write-through to persistent store.
executeTransaction(cache);
} catch (Exception e) {
System.out.println("sumthin happened");
e.printStackTrace();
} finally {
// Distributed cache could be removed from cluster only by #destroyCache() call.
ignite.destroyCache("ItemCache");
}
} catch (Exception e) {
e.printStackTrace();
}
}
TestPersistentStore2#executeTransaction
private static void executeTransaction(IgniteCache<Integer, Item> cache) {
int id = 1;
try (Transaction tx = Ignition.ignite("acmecorp").transactions().txStart()) {
Item val = cache.get(id);
System.out.println("Read value: " + val);
val = cache.getAndPut(id, new Item(id, "n", "b", "t", "m", "d"));
System.out.println("Overwrote old value: " + val);
val = cache.get(id);
System.out.println("Read value: " + val);
tx.commit();
}
System.out.println("Read value after commit: " + cache.get(id));
// Clear entry from memory, but keep it in store.
cache.clear(id);
// Operations on this cache will not affect store.
IgniteCache<Integer, Item> cacheSkipStore = cache.withSkipStore();
System.out.println("Read value skipping store (expecting null): " + cacheSkipStore.get(id));
System.out.println("Read value with store lookup (expecting NOT null): " + cache.get(id));
// Expecting not null, since entry should be in memory since last call.
System.out.println("Read value skipping store (expecting NOT null): " + cacheSkipStore.get(id));
}
However I get the following exception in the cache.get(id) call of executeTransaction:
>>> Loaded 72 keys with backups in 648ms.
javax.cache.CacheException: class org.apache.ignite.IgniteCheckedException: Unknown pair [platformId=0, typeId=123254525]
at org.apache.ignite.internal.processors.cache.GridCacheUtils.convertToCacheException(GridCacheUtils.java:1312)
at org.apache.ignite.internal.processors.cache.IgniteCacheProxy.cacheException(IgniteCacheProxy.java:2630)
at org.apache.ignite.internal.processors.cache.IgniteCacheProxy.get(IgniteCacheProxy.java:1188)
at infoh415.project.test.TestPersistentStore2.executeTransaction(TestPersistentStore2.java:98)
at infoh415.project.test.TestPersistentStore2.<init>(TestPersistentStore2.java:69)
at infoh415.project.test.TestPersistentStore2.main(TestPersistentStore2.java:130)
Caused by: class org.apache.ignite.IgniteCheckedException: Unknown pair [platformId=0, typeId=123254525]
at org.apache.ignite.internal.util.IgniteUtils.cast(IgniteUtils.java:7229)
at org.apache.ignite.internal.util.future.GridFutureAdapter.resolve(GridFutureAdapter.java:258)
at org.apache.ignite.internal.util.future.GridFutureAdapter.get0(GridFutureAdapter.java:170)
at org.apache.ignite.internal.util.future.GridFutureAdapter.get(GridFutureAdapter.java:139)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.get0(GridCacheAdapter.java:4499)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.get(GridCacheAdapter.java:4480)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.get(GridCacheAdapter.java:1324)
at org.apache.ignite.internal.processors.cache.IgniteCacheProxy.get(IgniteCacheProxy.java:1181)
... 3 more
Caused by: java.lang.ClassNotFoundException: Unknown pair [platformId=0, typeId=123254525]
at org.apache.ignite.internal.MarshallerContextImpl.getClassName(MarshallerContextImpl.java:392)
at org.apache.ignite.internal.MarshallerContextImpl.getClass(MarshallerContextImpl.java:342)
at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:686)
at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1755)
at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1714)
at org.apache.ignite.internal.binary.BinaryObjectImpl.deserializeValue(BinaryObjectImpl.java:797)
at org.apache.ignite.internal.binary.BinaryObjectImpl.value(BinaryObjectImpl.java:143)
at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinary(CacheObjectUtils.java:161)
at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinaryIfNeeded(CacheObjectUtils.java:41)
at org.apache.ignite.internal.processors.cache.CacheObjectContext.unwrapBinaryIfNeeded(CacheObjectContext.java:125)
at org.apache.ignite.internal.processors.cache.GridCacheContext.unwrapBinaryIfNeeded(GridCacheContext.java:1734)
at org.apache.ignite.internal.processors.cache.GridCacheContext.unwrapBinaryIfNeeded(GridCacheContext.java:1722)
at org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture.setResult(GridPartitionedSingleGetFuture.java:645)
at org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture.localGet(GridPartitionedSingleGetFuture.java:438)
at org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture.mapKeyToNode(GridPartitionedSingleGetFuture.java:324)
at org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture.map(GridPartitionedSingleGetFuture.java:212)
at org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture.init(GridPartitionedSingleGetFuture.java:204)
at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.getAsync0(GridDhtAtomicCache.java:1445)
at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.access$1600(GridDhtAtomicCache.java:129)
at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache$16.apply(GridDhtAtomicCache.java:513)
at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache$16.apply(GridDhtAtomicCache.java:511)
at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.asyncOp(GridDhtAtomicCache.java:806)
at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.getAsync(GridDhtAtomicCache.java:511)
... 7 more
Disconnected from the target VM, address: '127.0.0.1:49513', transport: 'socket'
I double checked the differences between the CacheConfiguration for CustomerCache and for ItemCache, there is nothing unexpected (the only differnces are in the table and field names). I also compared the model classes, again they are similar.
Attaching here the config of CustomerCache
/**
* Create configuration for cache "CustomerCache".
*
* #return Configured cache.
* #throws Exception if failed to create cache configuration.
**/
public static CacheConfiguration cacheCustomerCache() throws Exception {
CacheConfiguration ccfg = new CacheConfiguration();
ccfg.setName("CustomerCache");
ccfg.setCacheMode(CacheMode.PARTITIONED);
ccfg.setAtomicityMode(CacheAtomicityMode.ATOMIC);
CacheJdbcPojoStoreFactory cacheStoreFactory = new CacheJdbcPojoStoreFactory();
cacheStoreFactory.setDataSourceFactory(new Factory<DataSource>() {
/** {#inheritDoc} **/
#Override public DataSource create() {
return DataSources.INSTANCE_dsSQLServer_Acmecorp;
};
});
cacheStoreFactory.setDialect(new SQLServerDialect());
cacheStoreFactory.setTypes(jdbcTypeCustomer(ccfg.getName()));
ccfg.setCacheStoreFactory(cacheStoreFactory);
ccfg.setReadThrough(true);
ccfg.setWriteThrough(true);
ArrayList<QueryEntity> qryEntities = new ArrayList<>();
QueryEntity qryEntity = new QueryEntity();
qryEntity.setKeyType("java.lang.Integer");
qryEntity.setValueType("infoh415.project.model.Customer");
qryEntity.setKeyFieldName("customerId");
HashSet<String> keyFields = new HashSet<>();
keyFields.add("customerId");
qryEntity.setKeyFields(keyFields);
LinkedHashMap<String, String> fields = new LinkedHashMap<>();
fields.put("firstName", "java.lang.String");
fields.put("lastName", "java.lang.String");
fields.put("address", "java.lang.String");
fields.put("customerId", "java.lang.Integer");
qryEntity.setFields(fields);
HashMap<String, String> aliases = new HashMap<>();
aliases.put("customerId", "customer_id");
aliases.put("firstName", "first_name");
aliases.put("lastName", "last_name");
qryEntity.setAliases(aliases);
qryEntities.add(qryEntity);
ccfg.setQueryEntities(qryEntities);
return ccfg;
}
/**
* Create JDBC type for "jdbcTypeCustomer".
*
* #param cacheName Cache name.
* #return Configured JDBC type.
**/
private static JdbcType jdbcTypeCustomer(String cacheName) {
JdbcType type = new JdbcType();
type.setCacheName(cacheName);
type.setKeyType(Integer.class);
type.setValueType("infoh415.project.model.Customer");
type.setDatabaseSchema("dbo");
type.setDatabaseTable("Customer");
type.setKeyFields(new JdbcTypeField(Types.INTEGER, "customer_id", int.class, "customerId"));
type.setValueFields(
new JdbcTypeField(Types.VARCHAR, "first_name", String.class, "firstName"),
new JdbcTypeField(Types.VARCHAR, "last_name", String.class, "lastName"),
new JdbcTypeField(Types.VARCHAR, "address", String.class, "address")
);
return type;
}
vs. config of ItemCache
/**
* Create configuration for cache "ItemCache".
*
* #return Configured cache.
* #throws Exception if failed to create cache configuration.
**/
public static CacheConfiguration cacheItemCache() throws Exception {
CacheConfiguration ccfg = new CacheConfiguration();
ccfg.setName("ItemCache");
ccfg.setCacheMode(CacheMode.PARTITIONED);
ccfg.setAtomicityMode(CacheAtomicityMode.ATOMIC);
CacheJdbcPojoStoreFactory cacheStoreFactory = new CacheJdbcPojoStoreFactory();
cacheStoreFactory.setDataSourceFactory(new Factory<DataSource>() {
/** {#inheritDoc} **/
#Override public DataSource create() {
return DataSources.INSTANCE_dsSQLServer_Acmecorp;
};
});
cacheStoreFactory.setDialect(new SQLServerDialect());
cacheStoreFactory.setTypes(jdbcTypeItem(ccfg.getName()));
ccfg.setCacheStoreFactory(cacheStoreFactory);
ccfg.setReadThrough(true);
ccfg.setWriteThrough(true);
ArrayList<QueryEntity> qryEntities = new ArrayList<>();
QueryEntity qryEntity = new QueryEntity();
qryEntity.setKeyType("java.lang.Integer");
qryEntity.setValueType("infoh415.project.model.Item");
qryEntity.setKeyFieldName("itemId");
HashSet<String> keyFields = new HashSet<>();
keyFields.add("itemId");
qryEntity.setKeyFields(keyFields);
LinkedHashMap<String, String> fields = new LinkedHashMap<>();
fields.put("name", "java.lang.String");
fields.put("brand", "java.lang.String");
fields.put("type", "java.lang.String");
fields.put("manufacturer", "java.lang.String");
fields.put("description", "java.lang.String");
fields.put("itemId", "java.lang.Integer");
qryEntity.setFields(fields);
HashMap<String, String> aliases = new HashMap<>();
aliases.put("itemId", "item_id");
qryEntity.setAliases(aliases);
qryEntities.add(qryEntity);
ccfg.setQueryEntities(qryEntities);
return ccfg;
}
/**
* Create JDBC type for "jdbcTypeItem".
*
* #param cacheName Cache name.
* #return Configured JDBC type.
**/
private static JdbcType jdbcTypeItem(String cacheName) {
JdbcType type = new JdbcType();
type.setCacheName(cacheName);
type.setKeyType(Integer.class);
type.setValueType("infoh415.project.model.Item");
type.setDatabaseSchema("dbo");
type.setDatabaseTable("Item");
type.setKeyFields(new JdbcTypeField(Types.INTEGER, "item_id", int.class, "itemId"));
type.setValueFields(
new JdbcTypeField(Types.VARCHAR, "name", String.class, "name"),
new JdbcTypeField(Types.VARCHAR, "brand", String.class, "brand"),
new JdbcTypeField(Types.VARCHAR, "type", String.class, "type"),
new JdbcTypeField(Types.VARCHAR, "manufacturer", String.class, "manufacturer"),
new JdbcTypeField(Types.VARCHAR, "description", String.class, "description")
);
return type;
}
Model class of Customer
package infoh415.project.model;
import java.io.Serializable;
/**
* Customer definition.
*
* This file was generated by Ignite Web Console (11/26/2017, 10:52)
**/
public class Customer implements Serializable {
/** */
private static final long serialVersionUID = 0L;
private int customerId;
/** Value for firstName. */
private String firstName;
/** Value for lastName. */
private String lastName;
/** Value for address. */
private String address;
public Customer(String firstName, String lastName, String address) {
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
}
public Customer(int customerId, String firstName, String lastName, String address) {
this.customerId = customerId;
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
}
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
/**
* Gets firstName
*
* #return Value for firstName.
**/
public String getFirstName() {
return firstName;
}
/**
* Sets firstName
*
* #param firstName New value for firstName.
**/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* Gets lastName
*
* #return Value for lastName.
**/
public String getLastName() {
return lastName;
}
/**
* Sets lastName
*
* #param lastName New value for lastName.
**/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* Gets address
*
* #return Value for address.
**/
public String getAddress() {
return address;
}
/**
* Sets address
*
* #param address New value for address.
**/
public void setAddress(String address) {
this.address = address;
}
/** {#inheritDoc} **/
#Override public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Customer))
return false;
Customer that = (Customer)o;
if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null)
return false;
if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null)
return false;
if (address != null ? !address.equals(that.address) : that.address != null)
return false;
return true;
}
/** {#inheritDoc} **/
#Override public int hashCode() {
int res = firstName != null ? firstName.hashCode() : 0;
res = 31 * res + (lastName != null ? lastName.hashCode() : 0);
res = 31 * res + (address != null ? address.hashCode() : 0);
return res;
}
/** {#inheritDoc} **/
#Override public String toString() {
return "Customer [" +
"firstName=" + firstName + ", " +
"lastName=" + lastName + ", " +
"address=" + address +
"]";
}
}
Model class of Item
package infoh415.project.model;
import java.io.Serializable;
/**
* Item definition.
*
* This file was generated by Ignite Web Console (11/26/2017, 10:52)
**/
public class Item implements Serializable {
/** */
private static final long serialVersionUID = 0L;
private int itemId;
/** Value for name. */
private String name;
/** Value for brand. */
private String brand;
/** Value for type. */
private String type;
/** Value for manufacturer. */
private String manufacturer;
/** Value for description. */
private String description;
public Item(String name, String brand, String type, String manufacturer, String description) {
this.name = name;
this.brand = brand;
this.type = type;
this.manufacturer = manufacturer;
this.description = description;
}
public Item(int itemId, String name, String brand, String type, String manufacturer, String description) {
this.itemId = itemId;
this.name = name;
this.brand = brand;
this.type = type;
this.manufacturer = manufacturer;
this.description = description;
}
public int getItemId() {
return itemId;
}
public void setItemId(int itemId) {
this.itemId = itemId;
}
/**
* Gets name
*
* #return Value for name.
**/
public String getName() {
return name;
}
/**
* Sets name
*
* #param name New value for name.
**/
public void setName(String name) {
this.name = name;
}
/**
* Gets brand
*
* #return Value for brand.
**/
public String getBrand() {
return brand;
}
/**
* Sets brand
*
* #param brand New value for brand.
**/
public void setBrand(String brand) {
this.brand = brand;
}
/**
* Gets type
*
* #return Value for type.
**/
public String getType() {
return type;
}
/**
* Sets type
*
* #param type New value for type.
**/
public void setType(String type) {
this.type = type;
}
/**
* Gets manufacturer
*
* #return Value for manufacturer.
**/
public String getManufacturer() {
return manufacturer;
}
/**
* Sets manufacturer
*
* #param manufacturer New value for manufacturer.
**/
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
/**
* Gets description
*
* #return Value for description.
**/
public String getDescription() {
return description;
}
/**
* Sets description
*
* #param description New value for description.
**/
public void setDescription(String description) {
this.description = description;
}
/** {#inheritDoc} **/
#Override public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Item))
return false;
Item that = (Item)o;
if (name != null ? !name.equals(that.name) : that.name != null)
return false;
if (brand != null ? !brand.equals(that.brand) : that.brand != null)
return false;
if (type != null ? !type.equals(that.type) : that.type != null)
return false;
if (manufacturer != null ? !manufacturer.equals(that.manufacturer) : that.manufacturer != null)
return false;
if (description != null ? !description.equals(that.description) : that.description != null)
return false;
return true;
}
/** {#inheritDoc} **/
#Override public int hashCode() {
int res = name != null ? name.hashCode() : 0;
res = 31 * res + (brand != null ? brand.hashCode() : 0);
res = 31 * res + (type != null ? type.hashCode() : 0);
res = 31 * res + (manufacturer != null ? manufacturer.hashCode() : 0);
res = 31 * res + (description != null ? description.hashCode() : 0);
return res;
}
/** {#inheritDoc} **/
#Override public String toString() {
return "Item [" +
"name=" + name + ", " +
"brand=" + brand + ", " +
"type=" + type + ", " +
"manufacturer=" + manufacturer + ", " +
"description=" + description +
"]";
}
}
Can somebody please explain what the "class org.apache.ignite.IgniteCheckedException: Unknown pair [platformId=0, typeId=123254525]" error means and how to trace the cause of this issue - I already tried stepping through the Ignite code in debug mode, I know that in MarshallerContextImpl#getClassName the first line MappedName mappedName = cache.get(typeId); yields null for Item. But I do not understand why. Any help would be appreciated!! Thank you.
UPDATE:
Ignite version used: ignite-core 2.2.0
Update: content of loadCache:
private static void loadCache(IgniteCache<Integer, Item> cache) {
long start = System.currentTimeMillis();
// Start loading cache from persistent store on all caching nodes.
// cache.loadCache(null, ENTRY_COUNT);
cache.loadCache(null);
long end = System.currentTimeMillis();
System.out.println(">>> Loaded " + cache.size() + " keys with backups in " + (end - start) + "ms.");
}
Table definition of the Item table:
create table Item
(
item_id int not null
primary key,
name varchar(50) not null,
brand varchar(20) not null,
type varchar(20) not null,
manufacturer varchar(30) not null,
description varchar(200)
)
I can reproduce it when, in loadCaches(), I put something that isn't exactly the expected Item in the cache:
private void loadCache(IgniteCache<Integer, Item> cache, /* Ignite.binary() */ IgniteBinary binary) {
// Note the absence of package name here:
BinaryObjectBuilder builder = binary.builder("Item");
builder.setField("name", "a");
builder.setField("brand", "B");
builder.setField("type", "c");
builder.setField("manufacturer", "D");
builder.setField("description", "e");
builder.setField("itemId", 1);
cache.withKeepBinary().put(1, builder.build());
}
Please share your loadCaches method for scrutiny.
I have been getting trouble with my program and can't figure out why I am getting this error which has been bugging me. Any suggestion will be of huge assistance! I don't know if i am missing something or something like that. I have correctly imported the Array Class.
private String title;
private ArrayList<Student> students;
private int courseId;
private static int courseIdList = 0;
/**
*
*/
public Course(String tile)
{
this.title = title;
courseId = courseIdList;
courseIdList++;
students = new ArrayList<Student>();
}
/**
* #param returns the title
*/
public String getTitle(String title)
{
return title;
}
/**
* #return returns the ID
*/
public int getId()
{
return courseId;
}
/**
*
*/
public void addStudent(Student students)
{
for(int i = 0; i < students.size(); i++)
{
if(students.getId() != students.get(i).getId())
{
students.add(i);
return;
}
}
}
/**
*
*/
public void removeStudent(Student students)
{
for(int i = 0; i < students.size(); i++)
{
if(students.getId() == students.get(i).getId())
{
students.remove(i);
return;
}
}
}
/**
* #return if class is above or equal to 10 then return true, else return false;
*/
public boolean isFull(Student students)
{
if(students.size() >= 30)
{
return true;
}
else
{
return false;
}
}
/**
* #returns if the class is below ten then return true, else return false
*/
public boolean cancel(Student students)
{
if( students.size() < 10)
{
return true;
}
else
{
return false;
}
}
/**
*
*/
public ArrayList<Student> getStudents()
{
return students;
}
/**
*
*/
public boolean inClass(Student students)
{
for(int i = 0; i < students.size(); i++)
{
if(student.getId() == students.get(i).getId())
{
return true;
}
}
return false;
}
/**
* boolean returns true if a student's ID mathes and false if their ID does not.
*/
public boolean equals(Student s)
{
if(this.getId() == s.getId())
{
return true;
}
return false;
}
/**
*
*/
public double getAverage()
{
double sum = 0;
for(Student s : students)
{
sum += s.getGrade();
}
double avg = sum / students.size();
return avg;
}
/**
*
*/
public void getHighestGrade()
{
int highestGrade = 0;
for(Student s : students)
{
if(students.getGrade() > s.get(i).getGrade())
{
students.highestGrade(i);
}
}
return new Student(" ", 0,0);
}
/**
*
*/
public ArrayList<Student> getWarnings()
{
for(i = 0; i < students.size; i++)
{
if (students.getGrade() <= 70)
{
return students;
}
}
}
/**
*
*/
public void removeSeniors(Student students)
{
for(i = 0; i < students.size; i++)
{
if(students.getId() == students.get(i).subString(0,2).equalsTo(17))
{
students.remove(i);
}
}
}
/**
*
*/
public void sortByGrade()
{
}
/**
*
*/
public void sortByAlpha()
{
}
/**
*
*/
public String toString()
{
String printOut = "";
printOut += "Course name: " + title + "\nStudent ID: " + courseId;
return printOut;
for(Student students : students)
{
printOut += students.toString() + "\n";
}
}
}
Now its the opposite :) students is a List and not a Student. You need to loop over the list and process each student.
public void doSomething(List<Student> students) {
// does not work because students is a List of students not a student.
students.getId(); // ERROR
// loop over the list and then get the id of a single student
for(Student student : students) {
int id = student.getId();
// do something with the id
}
}
size() is a method of the List interface
getId() is a method of your Student class.
My issue is this : When I'm drawing a random card from the deck i've instantiated the returns are sometimes correct(i.e. KING_CLUBS) but sometimes I get a weird one (i.e. SEVEN_). This is odd because when the decks are instantiated, I added a print line statement in the Deck constructor to see if the ID's were being added correctly. Every time without fail the card id's are correct.
The println in Blackjack's hitUser() method was to check the ID of the card being drawn. Sometimes it's correct other times it's not. Can anyone tell me what's happening and why?
Runnable relevant code below
My Card Class:
import java.util.*;
import javax.swing.*;
import java.awt.*;
public class Card {
//cardValues[] represents the tangible values attached to the card faces(ACE, ONE, TWO, THREE, ..., KING)
private final static int cardValues[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
private final static String cardIDs[] = {"ACE_", "TWO_", "THREE_", "FOUR_", "FIVE_", "SIX_", "SEVEN_", "EIGHT_", "NINE_", "TEN_", "JACK_", "QUEEN_", "KING_"};
private int value;
//Name of the card, i.e. "ACE";
private String cardID;
/**
* Constructor
* #param v - card value(I.e. 1 for Ace or 13 for King)
*/
public Card(int v){
setValue(v);
setCardID(v);
}
/**
* Constructor
* #param v - card value(I.e. 1 for Ace or 13 for King)
* #param id - a manually set ID for the card(used for 'illegal' card instantiation)
*/
public Card(int v, String id){
setValue(v);
setCardID(id);
}
/**
* Returns the card ID
* #return - the card ID of the respective card
*/
public String getCardID(){
return cardID;
}
/**
* Returns the card value
* #return - the number value of the respective card
*/
public int getValue(){
return value;
}
/**
* Setter method for card value
* #param v - value
*/
public void setValue(int v){
//Checks to see if v is a valid cardValue
if(v >= 1 && v <= 13){
value = v;
}
}
/**
* 'legal' setter method for card ID
* #param v - number value of the card
*/
public void setCardID(int v){
//Checks to see if v is a valid cardValue
if(v >= 1 && v <= 13){
cardID = cardIDs[v - 1];
}
}
/**
* 'illegal' setter method for card ID
* #param id - String value of the card ID
*/
public void setCardID(String id){
cardID = id;
}
public String getIcon(){
return "blackjack/" + this.getCardID() + ".png";
}
My Deck Class:
import java.util.*;
import javax.swing.*;
import java.awt.*;
public class Deck {
private int numCards;
private String cardSuits[] = {"SPADES", "HEARTS", "DIAMONDS", "CLUBS"};
private static ArrayList<Card> cards = new ArrayList<Card>();
public static JLabel[] cardIcons = new JLabel[52];
public static int dealerHand, playerHand;
/**
* Constructor
*/
public Deck(){
//Will keep track of the index of the 52 cards created
int counter = 0;
for(int y = 0; y < 4; y++){
String suit = cardSuits[y];
for(int z = 1; z < 14; z++){
//Adds a new card and initializes it with its number value
cards.add(new Card(z));
//Replaces the card ID with a new ID containing the card suit (i.e. SPADES)
if(cards.get(counter).getCardID().indexOf("_") == cards.get(counter).getCardID().length() - 1){
String newID = cards.get(counter).getCardID() + suit;
cards.get(counter).setCardID(newID);
System.out.println(newID);
counter++;
} else {
}
}
}
}
/**
* Removes a card from the deck - gets rid of the object in the array of cards once it has been drawn
* #param id - the card to be removed
*/
public void removeCard(String id){
for(int i = 0; i < 52; i++){
if(cards.get(i).getCardID().equalsIgnoreCase(id)){
cards.remove(i);
}
}
}
/**
* Returns the object of the card within a deck
* #param c - the index of the card within the deck
* #return the card object
*/
public Card getCard(int c){
return cards.get(c);
}
/**
* Returns a random card from the array of cards in the deck
* #return - a random card object
*/
public Card getRandomCard(){
Random r = new Random();
int index = r.nextInt(cards.size());
return cards.get(index);
}
/**
* Resets the deck to its original, 'perfect' order
*/
public void reset(){
for(int x = 0; x<cards.size(); x++){
cards.remove(x);
}
//Will keep track of the index of the 52 cards created
int counter = 0;
for(int y = 0; y < 4; y++){
String suit = cardSuits[y];
for(int z = 0; z < 13; z++){
//Adds a new card and initializes it with its number value
cards.add(new Card(z));
//Replaces the card ID with a new ID containing the card suit (i.e. SPADES)
String newID = cards.get(counter).getCardID() + suit;
cards.get(counter).setCardID(newID);
counter++;
}
}
}
My Blackjack Class:
import javax.swing.*;
import net.miginfocom.swing.MigLayout;
/**
* This class provides all of the functionality of the blackjack game
* #author Mohamed Amadou
*
*/
public class Blackjack extends JFrame implements ActionListener{
public MigLayout mig = new MigLayout("insets 0");
public Deck bjDeckHouse = new Deck(), bjDeckUser = new Deck();
public int dealerOffset = 65, userOffset = 65, houseHand = 0,
public final int MAX_BET = 100000;
public JPanel bj = new JPanel(new MigLayout("insets 0")), blackjack = new JPanel(new MigLayout("insets 0"));
public JButton hit;
public Blackjack(){
buildUI();
mig.layoutContainer(bj);
setSize(780, 700);
setResizable(false);
setLayout(mig);
setTitle("Blackjack");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
}
public void buildUI(){
getContentPane().add(bj);
bj.setBackgroundColor(Color.BLACK);
hit = new JButton("Hit");
hit.addActionListener(this);
bj.add(hit, "pos 570px 285px");
}
public void hitUser(int hand){
JPanel test = new JPanel(new MigLayout("insets 0"));
JFrame testFrame = new JFrame();
testFrame.add(test);
Card hitCard = bjDeckUser.getRandomCard();
hand += hitCard.getValue();
String position = "pos "+ userOffset + "px" + " 580px";
System.out.println(hitCard.getCardID());
bjDeckUser.removeCard(hitCard.getCardID());
turns++;
checkBust(hand);
testFrame.setSize(400, 400);
testFrame.setResizable(false);
testFrame.setLayout(mig);
testFrame.setTitle("Blackjack Rules");
testFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
testFrame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == hit){
hitUser(userHand);
}
}
Your problem lies in reset():
for(int x = 0; x<cards.size(); x++){
cards.remove(x);
}
This actually does not remove all items (just play it through), you should use cards.clear(). Since the deck is then not empty, and you add another 52 cards, the deck will be incorrect. Additionally you will get weird names, probably also SEVEN_CLUBS_SPADES and similar.
Also, your code is a little bit confusing. Suite should be an attribute of a Card, not of a Deck. Cards should be immutable (maybe enums depending on usage). You have 2 initialization code snippets (you should have 1). GUI code in your "business model". Just a few ideas to clean up :)
I am a beginner and I am trying to understand what is static, private, public. Please see the following example written by me. It works, but I have very big doubts whether this is a correct way of defining variables and methods. Thanks in advance!
import java.util.Scanner;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class Biorhytm {
private static String nameOne;
private static String nameTwo;
private static String dobOneIn;
private static String dobTwoIn;
private static Date dobOne;
private static Date dobTwo;
static int diff;
public static Date getDobOne() {
return dobOne;
}
public static void setDobOne(Date dobOne) {
Biorhytm.dobOne = dobOne;
}
public static Date getDobTwo() {
return dobTwo;
}
public static void setDobTwo(Date dobTwo) {
Biorhytm.dobTwo = dobTwo;
}
public static String getDobOneIn() {
return dobOneIn;
}
public static void setDobOneIn(String dobOneIn) {
Biorhytm.dobOneIn = dobOneIn;
}
public static String getDobTwoIn() {
return dobTwoIn;
}
public static void setDobTwoIn(String dobTwoIn) {
Biorhytm.dobTwoIn = dobTwoIn;
}
public static String getNameOne() {
return nameOne;
}
public static void setNameOne(String nameOne) {
Biorhytm.nameOne = nameOne;
}
public static String getNameTwo() {
return nameTwo;
}
public static void setNameTwo(String nameTwo) {
Biorhytm.nameTwo = nameTwo;
}
public static int diffCalc() {
return diff = Math.abs((int)((getDobOne().getTime() - getDobTwo().getTime()) / (24 * 60 * 60 * 1000)));
}
public static void main(String[] args) {
float physicalBio;
float emotionalBio;
float intellectualBio;
boolean validEntry;
Scanner input = new Scanner(System.in);
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy");
SimpleDateFormat format2 = new SimpleDateFormat("EEEE, MMMM d, yyyy", java.util.Locale.US);
System.out.println("Enter name of first person!");
setNameOne(input.nextLine());
if (getNameOne().equals("")) {
setNameOne("first person");
}
System.out.println("Enter name of second person!");
setNameTwo(input.nextLine());
if (getNameTwo().equals("")) {
setNameTwo("second person");
}
do {
try {
System.out.println("Enter date of birth of " + getNameOne() + "! (MM/DD/YYYY)");
setDobOneIn(input.nextLine());
setDobOne(format.parse(getDobOneIn()));
validEntry = true;
}
catch (ParseException e) {
validEntry = false;
}
} while (!validEntry);
do {
try {
System.out.println("Enter date of birth of " + getNameTwo() + "! (MM/DD/YYYY)");
setDobTwoIn(input.nextLine());
setDobTwo(format.parse(getDobTwoIn()));
validEntry = true;
}
catch (ParseException e) {
validEntry = false;
}
} while (!validEntry);
System.out.println();
System.out.println("DOB of " + getNameOne() + ": " + format2.format(getDobOne()) + ".");
System.out.println("DOB of " + getNameTwo() + ": " + format2.format(getDobTwo()) + ".");
System.out.println("Difference between DOBs (days): " + diffCalc() + ".");
physicalBio = diffCalc() % 23;
emotionalBio = diffCalc() % 28;
intellectualBio = diffCalc() % 33;
physicalBio /= 23;
emotionalBio /= 28;
intellectualBio /= 33;
if (physicalBio > 0.5) {
physicalBio = 1 - physicalBio;
}
if (emotionalBio > 0.5) {
emotionalBio = 1 - emotionalBio;
}
if (intellectualBio > 0.5) {
intellectualBio = 1 - intellectualBio;
}
physicalBio = 100 - (physicalBio * 100);
emotionalBio = 100 - (emotionalBio * 100);
intellectualBio = 100 - (intellectualBio * 100);
System.out.println("Physical compatibility: " + java.lang.Math.round(physicalBio) + " %.");
System.out.println("Emotional compatibility: " + java.lang.Math.round(emotionalBio) + " %.");
System.out.println("Intellectual compatibility: " + java.lang.Math.round(intellectualBio) + " %.");
}
}
You'd rather have your Biorhythm class be something representing the data about a single person. So you'd create two instances of it (call them "one" and "two", say) and make them non-static. It would have instance variables, not static variables, representing name and date of birth.
class Biorhythm {
private Date dob;
private String name;
Biorhythm(String name, Date dob) {
this.name = name;
this.dob = dob;
}
public String getName() {
return name;
}
public Date getDob() {
return dob;
}
}
public static void main(String[] args) {
Date onedob = /* implementation omitted */
Biorhythm one = new Biorhythm("maxval", onedob);
System.out.println("one: name=" + one.getName() + " date=" + one.getDob());
/* and so forth */
}
You don't really have a need for setXXX() methods because these values aren't probably going to change in your program.
Now create two instances of this class in your main() method. I'll leave the implementation of the calculation methods as an exercise for the time being, since there would be several decent designs for implementing them (in terms of the object-oriented question you asked).
First let me explain what these keywords are-
private,default,protected.public are ACCESS SPECIFIERS.
public-as the word says ,can be accessed everywhere and all members can be public.
protected-can be accessed outside the package in case of inheritance.
default-access able within the package and all members can be default.
private-scope lies within the class,cant be inherited.
And remember these can be used with variables,methods,even classes.
static-can be used when there is no need to invoke methods or access variables with objects.
static members doesn't belong to object and initialised at the time of loading a class.
for ex:
class Converter{
public static long convert(long val){
return val;
}
class User{
long value=Converter.convert(500);//calling convert with class name}
hi my problem is that in my code i am calling a method that calculates the different between 2 point and then if that distance is less that 7 it will call another class method that should change the color of the target to red... my problem is that in my arraylist i have 3 or five or depends on the user input targets... so how can i specify the object in my arraylist that is going to be change of color>??? this is my code
package project1;
import java.util.*;
import javax.swing.*;
/**
*
* #author Elvis De Abreu
*/
public class TargetGallery
{
/**ArrayList of Targets initialize as a private*/
private ArrayList<Target> mytargets = new ArrayList<>();
/**Static object for the Target class*/
static Target tg = new Target();
/**Static object for the RifleSite class*/
static RifleSite rs = new RifleSite();
/**Static object for the TargetGallery class*/
static TargetGallery tgy = new TargetGallery();
/**the number of targets input by the user as private*/
private int number = 0;
/**array that store the distance between 2 point for each target*/
private double[] total;
/**
* Method that build the background of the canvas
* with a picture as a environment
*/
private void buildWorld()
{
StdDraw.setXscale(0, 250);
StdDraw.setYscale(0, 250);
StdDraw.picture(75, 130, "bath.jpeg", 450, 285);
}
/**
* Method that draw a weapon in the middle of the
* canvas as a shooter weapon
*/
private void drawShooter()
{
StdDraw.setXscale(0, 250);
StdDraw.setYscale(0, 250);
StdDraw.picture(125, 0, "weapon.png", 80, 45);
}
/**
* randomly generates X locations for the targets
* add them into the array list
*/
private void createTargets()
{
double x = 125;
double y = 175;
double radius = 7;
String input = JOptionPane.showInputDialog("Type a number" +
"between 2 and 5");
number = Integer.parseInt(input);
for(int i = 0; i < number; i++)
{
Target targ = new Target(x, y, radius);
mytargets.add(targ);
Random rand = new Random();
x = rand.nextInt(400) + 10;
for (Target e: mytargets)
{
if ((e.getX() <= (x+10)) || (e.getX() >= (x-10)))
{
mytargets.clear();
i--;
continue;
}
}
}
}
/**
* Method that run different methods which start the program
*/
public void run()
{
tgy.buildWorld(); //call the buildWorld method
tgy.drawShooter(); //call the drawShooter method
tgy.createTargets(); //call the createTarget method
tgy.simulate(); //call the simulate method
}
/**
* calculates the distance between the RifleSite and the Targets
*/
public void calcDistance()
{
//variable declaration/initialization
double distance;
double distance1;
int i = 0;
total = new double[number];
//for each loop to calculate x and y location of RifleSite and Targets
for (Target e: mytargets)
{
distance = Math.pow(e.getX()-rs.getX(), 2.0);
distance1 = Math.pow(e.getY()-rs.getY(), 2.0);
total[i++] = Math.sqrt(distance + distance1);
}
}
/**
* Method that simulates the game
*/
public void simulate()
{
//Variable declaration/initialization
boolean alive = true;
for(Target e: mytargets)
{
e.drawAlive();
}
rs.drawRifleSite();
//loop that will run while there is still targets alive or user press q
while(alive == true)
{
//if user press a key this
if (StdDraw.hasNextKeyTyped())
{
char ch = StdDraw.nextKeyTyped(); //store the key pressed
//if person press Q will quit the program
if (ch == 'q')
{
int done = JOptionPane.showConfirmDialog(null,
"The Program will close now bye :)");
System.exit(0);
}
else if (ch == 'f')
{
tgy.calcDistance(); //calculates the distance
//if statement to check if the distance if less than radius
for(int i = 0; i < number; i++)
{
if (total[i] <= 7)
{
//THIS IS WHERE MY METHOD SHOULD GO
//SHOULD BE SOMETHING LIKE E.drawDead
}
}
}
}
}
}
/**
* Method for the main of the Program
* #param args the command line arguments
*/
public static void main(String[] args)
{
}
}
Like this:mytargets.get(INDEX GO HERE)
i Hope that helps
(the index starts from 0)
For example:
Target t=mytargets.get(0);
if ((t.getX() > 10) && (t.getY() > 10))
{
//blablabla
}