Geotools Feature Tutorial ClassFormatError - geotools

I tried to work through the Feature Tutorial of geotools. Everything worked well until I got to the code where the Features should be stored in a shapefile:
if (featureSource instanceof SimpleFeatureStore) {
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
// List Features into Collection
SimpleFeatureCollection collection = new ListFeatureCollection(TYPE, features);
featureStore.setTransaction(transaction);
try {
featureStore.addFeatures(collection);
transaction.commit();
}catch (Exception problem) {
problem.printStackTrace();
transaction.rollback();
}finally {
transaction.close();
}
System.exit(0);
}else {
System.out.println(typeName + "does not support read/write access.");
System.exit(0);
}
The runtime exception links to the row "featureStore.addFeatures(collection);
This is the error message:
Exception in thread "main" java.lang.ClassFormatError: Illegal constant pool index 0 for method name in class file org/geotools/geometry/jts/JTS
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:821)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:719)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:642)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:600)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at org.geotools.feature.simple.SimpleFeatureImpl.getBounds(SimpleFeatureImpl.java:258)
at org.geotools.data.Diff.addToSpatialIndex(Diff.java:201)
at org.geotools.data.Diff.add(Diff.java:195)
at org.geotools.data.store.DiffContentFeatureWriter.write(DiffContentFeatureWriter.java:168)
at org.geotools.data.InProcessLockingManager$1.write(InProcessLockingManager.java:296)
at org.geotools.data.store.ContentFeatureStore.addFeature(ContentFeatureStore.java:302)
at org.geotools.data.store.ContentFeatureStore.addFeatures(ContentFeatureStore.java:254)
at de.topotools.topograph.Csv2Shape.main(Csv2Shape.java:121)
I updated the maven project and checked if the code is equal to the tutorial's code, but nothing helped. I could also not find any description of this error in relation to geotools searching the internet.
I'm using Java 14.0.2.
Thanks for your help.

It looks like your project is missing a jar or two. Also GeoTools doesn't really support any JVMs except 1.8 and 11, but always happy to hear it works in another versions.

Related

System.InvalidOperationException: A second operation started on this context before a previous operation completed in Blazor and EFCore

I have method like the DeleteSettingAbout() after in text, where I am still getting error: "System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.".
Code of the method is:
public async Task DeleteSettingAbout(int Id)
{
SettingAbout setting = await _context.SettingsAbout.FirstOrDefaultAsync(o => o.Id == Id);
if (setting != null)
{
_context.SettingsAbout.Remove(setting);
await _context.SaveChangesAsync();
}
}
In sartup.cs I set DBContext and DBRepository as Transient:
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("AppDBConnection")),
ServiceLifetime.Transient);
services.AddTransient<IAppDbRepository, SQLAppDbRepository>();
But I am still getting this error.
How to solve this behavior? Thanks for answers.
UPDATE 2021-01-06
I tried the approach with creating the "DbContextFactory" and it solved my problem. I got inspiration from sample app https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/blazor/common/samples/3.x/BlazorServerEFCoreSample (mentioned here: https://learn.microsoft.com/en-us/aspnet/core/blazor/blazor-server-ef-core?view=aspnetcore-3.1#sample-app-3x).
Now I have in my startup.cs this:
// new way suitable for Blazor - register factory and configure the options (new instance for each method call)
services.AddDbContextFactory<AppDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("AppDBConnection")));
services.AddScoped<IAppDbRepository, SQLAppDbRepository>();
I tried the approach with creating the "DbContextFactory" (mentioned by Stephen Cleary) and it solved my problem. I got inspiration from sample app https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/blazor/common/samples/3.x/BlazorServerEFCoreSample (mentioned here: https://learn.microsoft.com/en-us/aspnet/core/blazor/blazor-server-ef-core?view=aspnetcore-3.1#sample-app-3x).
Now I have in my startup.cs this:
// new way suitable for Blazor - register factory and configure the options (new instance for each method call)
services.AddDbContextFactory<AppDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("AppDBConnection")));
services.AddScoped<IAppDbRepository, SQLAppDbRepository>();
Note: I needed to solve the problem in EF/Blazor = v3.1 (because my web-hosting does not support v5 for now)
Thank you all for answers!

Spring Boot+ MySQL: LAZY Loading issue - No operations allowed after statement closed

I implement a Dashboard functionality that checks every time at program start a list of Requirement-Objects for a bunch of different characteristics like progress, missing data and alike and sets for each characteristic a dedicated beacon on the UI.
protected void initializePerformanceIndicator() {
try {
updateA();
updateB();
...
updateF();
updateG();
} catch (Exception e) {
ErrorHandler.showError("Cannot show KPI Performance", e);
}
}
The checks have different compute demands some are faster some slower, therefore each of this checks runs in a dedicated Task to provide some feedback to the user. The skeleton of such a Task is always the same
protected void updateA() throws Exception {
Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws Exception {
embeddedBudgetKPIController.setHyperlink("Budget", null);
embeddedBudgetKPIController.setToolTip("...");
ObservableList<UserRequirement> issues = FXCollections.observableArrayList();
List<UserRequirement> requirements = reqService.getAllUserRequirements(false); // all requirements of the selected product
for(UserRequirement req: requirements) {
if(*some criteria*) {
issues.add(req);
}
}
if(issues.isEmpty()) {
embeddedBudgetKPIController.setBeaconColor(Color.GREEN);
} else {
embeddedBudgetKPIController.setBeaconColor(Color.RED);
}
return null;
};
};
task.setOnSucceeded(e -> {
// Nothing to do
});
Thread tt = new Thread(task);
tt.start();
}
Before initializePerformanceIndicator is called, I retrieved already elsewhere the data from the database querying a number Spring Repositories:
protected final ObservableList<UserRequirement> allUserRequirements = FXCollections.observableArrayList();
public synchronized ObservableList<UserRequirement> getAllUserRequirements(boolean forceUpdate) throws Exception {
logger.debug(""); // show that this method is called
Product selectedProduct = SelectedScope.getSelectedProduct();
if(selectedProduct == null) {
throw new Exception("No selProduct selected");
}
if(forceUpdate || allUserRequirements.isEmpty()) {
allUserRequirements.clear();
allUserRequirements.addAll(epicRepository.findByProductAndRevisionSuccessorIsNull(selectedProduct));
allUserRequirements.addAll(themeRepository.findByProductAndRevisionSuccessorIsNull(selectedProduct));
allUserRequirements.addAll(userStoryRepository.findByProductAndRevisionSuccessorIsNull(selectedProduct));
allUserRequirements.addAll(tangibleRepository.findByProductAndRevisionSuccessorIsNull(selectedProduct));
}
return allUserRequirements;
}
and as you see updateBudgetKPIController calls getallUserRequirements with the parameter false. Therefore it returns the buffered result set and is not re-fetching data from database. So far everything is fine.
I can run each of these Tasks individually without problem. I tried a number combinations with 2 Tasks. Works fine, but the program will never show more than three or four beacons. Which ones are shown differs as well - what is expected as a consequence of the different Tasks. If I exceed three or four Tasks I often get no error at all, but the UI is just not showing more than three to four beacons.
Sometimes I do get an error message, which is
WARN 08:14 o.h.e.j.s.SqlExceptionHelper.logExceptions:137: SQL Error: 0, SQLState: S1009
ERROR 08:14 o.h.e.j.s.SqlExceptionHelper.logExceptions:142: No operations allowed after statement closed.
I debugged it, and realized that I was generating way too many select statements. The UserRequirement entity has almost a dozen OneToMany relations, some where defined with FetchType.LAZY, so I thought it would be better anyway to configure all these relations as
#OneToMany(fetch = FetchType.LAZY, mappedBy="parent", cascade = CascadeType.ALL)
Because of the LAZY loading, every Task tries to load additional data in the if(*some criteria*) part.
The problem did not disappear but I get more information, as the error is now
WARN 11:02 o.h.c.i.AbstractPersistentCollection.withTemporarySessionIfNeeded:278: Unable to close temporary session used to load lazy collection associated to no session
WARN 11:02 o.h.e.j.s.SqlExceptionHelper.logExceptions:137: SQL Error: 0, SQLState: S1009
ERROR 11:02 o.h.e.j.s.SqlExceptionHelper.logExceptions:142: No operations allowed after statement closed.
So I do have a LAZY loading issue.
I am using Spring Boot 2.1.6, MySQL 8.0.15 Community Server, Hibernate Core {5.3.10.Final}, Java 1.8.0_211 and the com.mysql.cj.jdbc.Driver
From a former issue, I have in my properties file the following configuration
# Prevent LazyInitializationException
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
Don't know whether this has a side effect?!
Probably changing the LAZY loading to EAGER will fix it - haven't tried yet - but it would delay program start significantly. Therefore I would prefer a solution with LAZY loading.
Any ideas? I also appreciate any ideas regarding how to further isolate the root cause as the error message is not really explicit and I can't see which part of my code triggers it. Plus when I debug it, the behavior changes as I compute all Tasks sequentially rather then in parallel. Thank you in advance.
The issue was caused by different Tasks accessing the same getter of some of the entities. If the first getter call opened a connection, the second call got on it, and then the first call closed the ResultSet, the second call one was in trouble. Synchronizing the getter method solved the problem.

How to recover from database errors in Grails within a transaction

In short, what I am trying solve is how to recover from certain database errors in a Grails application using Hibernate and continue on with the transaction skipping over the failed row updates that are part of a batch of changes.
The application uses Grails 2.3.11 but I have also tried with version 1.3.8 with similar failed results.
Basically there is a Grails service class that iterates over a list of imported records and attempts to update associated master records appropriately. In certain situations exceptions might occur during the domain.save(flush:true) call e.g. org.hibernate.exception.DataException thrown due to issues like (Data truncation: Data too long for column ...).
At this point I have tried:
Disabling transactions
Using domainObj.withTransaction() for each individual record
Trying various #Transactional annotations
Calling domain.clearErrors() and domain.discard() after catching the exception
Tried using a nested service with Transactional annotation with noRollbackFor as shown below
A number of other approaches but nothing I've tried has worked
Example code:
#Transactional
class UpdateService {
public updateBatch(Integer batchId) {
...
list.each { record ->
record.value = 123
try {
nestedService.saveDomain()
} catch (e) {
record.clearErrors()
record.discard()
}
}
batch.status = "POSTED"
batch.save()
}
}
#Transactional
class NestedService {
#Transactional(propagation = Propagation.REQUIRED, noRollbackFor = RuntimeException.class)
public void saveDomain(domainObj) throws RuntimeException {
if (domainObj.validate() && domainObj.save(flush:true) {
log.info "domain $domain was saved"
}
}
}
Once an error occurs I can't seem to clear out the hibernate session. On each subsequent record being updated I receive the error:
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction
where it indicates the original failed domain id.
Revision:
Vahid, Thanks for the suggestions. I have tried that. I realized one issue is that I am passing objects across transactional boundaries. So I experimented with the NestedService class do something along the lines of:
#Transactional(propagation = Propagation.REQUIRE_NEW)
public void saveDomain(domainObj) {
def newObj = new Domain.get(domainObj.id)
newObj.properties = domainObj.properties
if (newObj.validate() && newObj.save(force:true) ) { ... }
I expected that to work but the original domainObj still fails even though I'm not calling the save on it. Very strange...
A simple approach would be to loop and then use validate(). If it does fail, then just store the id of the failed entity and proceed.
if(!domainObject.validate()){
// store Id for trying it again later ?
}else{
// Save
}

Exception while calling savechange method while adding, removing or modifying entity. IMP

I am working on Entity Framework 4.1 . Here Adding control into database using AddObject() and save that suing SaveChange() methods.
But Once I delete that added control and try to add again same I am getting this error again and again (Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.) but not able to add it. Once i close my application then try to add then I am able to add that control.
I tried to search a lot here and there how it going wrong but could not find solution. As I am new born in field in Entity Framework.
As in this scenario i was calling SaveChange() method of Entity framework object context after every operation like add, delete and modification. But i was getting exception back to back.It got solved by
By calling method like this
public void Save(object entity)
{
using (var transaction = Connection.BeginTransaction())
{
try
{
SaveChanges();
transaction.Commit();
}
catch (OptimisticConcurrencyException)
{
if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Deleted || ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Modified)
this.Refresh(RefreshMode.StoreWins, entity);
else if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Added)
Detach(entity);
AcceptAllChanges();
transaction.Commit();
}
}
}

Mailing Exception logs in a live Grails webapp

I'd like my Grails web-app to send an e-mail for each exception that reaches the end-user.
Basically I'm looking for a elegant way to achieve something equivalent to:
try {
// ... all logic/db-access/etc required to render the page is executed here ...
}
catch (Exception e) {
sendmail("exception#example.com", "An exception was thrown while processing a http-request", e.toString);
}
Turns out this exact question was answered on the Grails mailing list a couple of days ago.
The solution is to add the following to the log4j-section of Config.groovy:
log4j {
...
appender.mail='org.apache.log4j.net.SMTPAppender'
appender.'mail.To'='email#example.com'
appender.'mail.From'='email#example.com'
appender.'mail.SMTPHost'='localhost'
appender.'mail.BufferSize'=4096
appender.'mail.Subject'='App Error'
appender.'mail.layout'='org.apache.log4j.PatternLayout'
appender.'mail.layout.ConversionPattern'='[%r] %c{2} %m%n'
rootLogger="error,stdout,mail"
...
// rootLogger="error,stdout" (old rootLogger)
}
Plus adding sun-javamail.jar and activation.jar to the lib/-folder.
Assuming you can do this from groovy, you'll want to use a logging framework such as log4j for this, which has loggers that can append log data to a database, send email, etc.
You could also take a look at exceptionHandler mechanism provided by Grails; I find it very simple; yet powerful enough to take care of all my custom & clean exception handling needs. Haven't tested this approach with 1.1 so far; but works very well with 1.0.3.
class BootStrap {
def exceptionHandler
def init = { servletContext ->
exceptionHandler.exceptionMappings =
[ 'NoSuchFlowExecutionException' :'/myControler/myAction',
'java.lang.Exception' : '/myController/generalAction']
}
def destroy = { }
}
Detailed blog here :
http://blog.bruary.net/2008/03/grails-custom-exception-handling.html