In our project we use an implementation of HL7 document from openehealth. This implementation uses EMF as primitive model and delegates all calls to EMF. We need to handle a large volume of documents and our flows involve concurrent processing of documents(read, validate, query). In concurrency environment the EMF layer crashes with UnsupportedOperationException. From openehealth site it says to handle the synchronized processing in the client api, but this will decrease our system performance and we don't want this. I tried EMF transaction API, TransactionalEditingDomain, which says that supports read only model transactions but without success. My test looks something like this:
ExecutorService executorService = Executors.newFixedThreadPool(4);
final List<ClinicalDocument> documents = new ArrayList<ClinicalDocument>();
for (int i = 0; i < 100; i ++) {
executorService.submit(new Runnable() {
#Override
public void run() {
try {
int randomNum = 1 + (int)(Math.random()*6);
ClinicalDocument cda = readCda();
processIntensiveWork(cda);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void processIntensiveWork(final ClinicalDocument document) {
for (final Method method : document.getClass().getMethods())
if (method.getName().startsWith("get")) {
try {
domain.runExclusive(new RunnableWithResult.Impl() {
#Override
public void run() {
try {
method.invoke(document);
System.out.println("Invoked method: " + method.getName());
setResult(null);
} catch (UnsupportedOperationException e) {
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
For this test case we frequently caught java.lang.UnsupportedOperationException.
I mention that for some test cases i also caught the the following error from EMF transaction API: java.lang.IllegalArgumentException: Can only deactivate the active transaction
Any suggestions are kindly appreciated. Feel free to ask other information that might help you in resolving the problem.
Related
I'm trying to ignore a exception that happen when run my test Methods.
I`m using a unitTest proyect.
The problem apears when
TestCleanup Method runs. It's a recursive method. This method clean all entities created in DB during the test. This is a recursive method because of dependences.
Anyway this method call to delete generic method in my ORM(Petapoco). It throws an exception if it can't delete the entity. Any problem, it run again with recursive way until delete it.
Now the problem, if i'm debugging VS stop a lot of times in Execute method because of failed deletes. But I can't modify this method to ignore it. I need a way to ignore this stops when i'm debugging tests. A way like DebuggerHiddenAttribute or similar.
Thanks!
I tried to use DebuggerHiddenAttribute, but cannot works in methods called by main method.
[TestCleanup(), DebuggerHidden]
public void CleanData()
{
ErrorDlt = new Dictionary<Guid, object>();
foreach (var entity in TestEntity.CreatedEnt)
{
try
{
CallingTest(entity);
}
catch (Exception e)
{
if (!ErrorDlt.ContainsKey(entity.Key))
ErrorDlt.Add(entity.Key, entity.Value);
}
}
if (ErrorDlt.Count > 0)
{
TestEntity.CreatedEnt = new Dictionary<Guid, object>();
ErrorDlt.ForEach(x => TestEntity.CreatedEnt.Add(x.Key, x.Value));
CleanData();
}
}
public int Execute(string sql, params object[] args)
{
try
{
OpenSharedConnection();
try
{
using (var cmd = CreateCommand(_sharedConnection, sql, args))
{
var retv = cmd.ExecuteNonQuery();
OnExecutedCommand(cmd);
return retv;
}
}
finally
{
CloseSharedConnection();
}
}
catch (Exception x)
{
OnException(x);
throw new DatabaseException(x.Message, LastSQL, LastArgs);
}
}
Error messages are not required.
I'm running the following test code on SolrCloud using Solrj library:
public static void main(String[] args) {
String zkHostString = "192.168.56.99:2181";
SolrClient solr = new CloudSolrClient.Builder().withZkHost(zkHostString).build();
List<MyBean> beans = new ArrayList<>();
for(int i = 0; i < 10000 ; i++) {
// creating a bunch of MyBean to be indexed
// and temporarily storing them in a List
// no Solr operations performed here
}
System.out.println("Adding...");
try {
solr.addBeans("myCollection", beans);
} catch (IOException | SolrServerException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Committing...");
try {
solr.commit("myCollection");
} catch (SolrServerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This code fails due to the following exception
Exception in thread "main" java.lang.NullPointerException
at org.apache.solr.client.solrj.impl.CloudSolrClient.requestWithRetryOnStaleState(CloudSolrClient.java:1175)
at org.apache.solr.client.solrj.impl.CloudSolrClient.request(CloudSolrClient.java:1057)
at org.apache.solr.client.solrj.SolrRequest.process(SolrRequest.java:160)
at org.apache.solr.client.solrj.SolrClient.add(SolrClient.java:106)
at org.apache.solr.client.solrj.SolrClient.addBeans(SolrClient.java:357)
at org.apache.solr.client.solrj.SolrClient.addBeans(SolrClient.java:312)
at com.togather.solr.testing.SolrIndexingTest.main(SolrIndexingTest.java:83)
This is the full stacktrace of the exception. I just "upgraded" from a Solr standalone installation to a SolrCloud (with an external Zookeeper single instance, not the embedded one). With standalone Solr the same code (with just some minor differences, like the host URL) used to work perfectly.
The NPE sends me inside the SolrJ library, which I don't know.
Anyone can help me understand where the problem originates from and how I can overcome it? Due to my unexperience and the brevity of the error message, I can't figure out where to start inquiring from.
Looking at your code, I would suggest to specify the default collection as first thing.
CloudSolrClient solr = new CloudSolrClient.Builder().withZkHost(zkHostString).build();
solr.setDefaultCollection("myCollection");
Regarding the NPE you're experiencing, very likely is due to a network error.
In these lines your exception is raised by for loop: for (DocCollection ext : requestedCollections)
if (wasCommError) {
// it was a communication error. it is likely that
// the node to which the request to be sent is down . So , expire the state
// so that the next attempt would fetch the fresh state
// just re-read state for all of them, if it has not been retired
// in retryExpiryTime time
for (DocCollection ext : requestedCollections) {
ExpiringCachedDocCollection cacheEntry = collectionStateCache.get(ext.getName());
if (cacheEntry == null) continue;
cacheEntry.maybeStale = true;
}
if (retryCount < MAX_STALE_RETRIES) {//if it is a communication error , we must try again
//may be, we have a stale version of the collection state
// and we could not get any information from the server
//it is probably not worth trying again and again because
// the state would not have been updated
return requestWithRetryOnStaleState(request, retryCount + 1, collection);
}
}
I am trying to implement the following use case as part of my akka learning
I would like to calculate the total streets in all cities of all states. I have a database that contain the details needed. Here is what i have so far
Configuration
akka.actor.deployment {
/CityActor{
router = random-pool
nr-of-instances = 10
}
/StateActor {
router = random-pool
nr-of-instances = 1
}}
Main
public static void main(String[] args) {
try {
Config conf = ConfigFactory
.parseReader(
new FileReader(ClassLoader.getSystemResource("config/forum.conf").getFile()))
.withFallback(ConfigFactory.load());
System.out.println(conf);
final ActorSystem system = ActorSystem.create("AkkaApp", conf);
final ActorRef masterActor = system.actorOf(Props.create(MasterActor.class), "Migrate");
masterActor.tell("", ActorRef.noSender());
} catch (Exception e) {
e.printStackTrace();
}
}
MasterActor
public class MasterActor extends UntypedActor {
private final ActorRef randomRouter = getContext().system()
.actorOf(Props.create(StateActor.class).withRouter(new akka.routing.FromConfig()), "StateActor");
#Override
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
getContext().watch(randomRouter);
for (String aState : getStates()) {
randomRouter.tell(aState, getSelf());
}
randomRouter.tell(new Broadcast(PoisonPill.getInstance()), getSelf());
} else if (message instanceof Terminated) {
Terminated ater = (Terminated) message;
if (ater.getActor().equals(randomRouter)) {
getContext().system().terminate();
}
}
}
public List<String> getStates() {
return new ArrayList<String>(Arrays.asList("CA", "MA", "TA", "NJ", "NY"));
};}
StateActor
public class StateActor extends UntypedActor {
private final ActorRef randomRouter = getContext().system()
.actorOf(Props.create(CityActor.class).withRouter(new akka.routing.FromConfig()), "CityActor");
#Override
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
System.out.println("Processing state " + message);
for (String aCity : getCitiesForState((String) message)) {
randomRouter.tell(aCity, getSelf());
}
Thread.sleep(1000);
}
}
public List<String> getCitiesForState(String stateName) {
return new ArrayList<String>(Arrays.asList("Springfield-" + stateName, "Salem-" + stateName,
"Franklin-" + stateName, "Clinton-" + stateName, "Georgetown-" + stateName));
};}
CityActor
public class CityActor extends UntypedActor {
#Override
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
System.out.println("Processing city " + message);
Thread.sleep(1000);
}
}}
Did i implement this use case properly?
I cannot get the code to terminate properly, i get dead letters messages. I know why i am getting them, but not sure how to properly implement it.
Any help is greatly appreciated.
Thanks
I tested and ran your use case with Akka 2.4.17. It works and terminate properly, without any dead letters logged.
Here are some remarks/suggestions to improve your understanding of the Akka toolkit:
Do not use Thread.sleep() inside an actor. Basically, it is never a good practice since a same thread may do many tasks for many actors (this is the default behavior with a shared thread pool). Instead, you can use an Akka scheduler or assign a single thread to a specific Actor (see this post for more details). See also the Akka documentation about that topic.
Having some dead letters is not always an issue. It generally arises when the system stops an Actor that had some messages within its mailbox. In this case, the remaining unprocessed messages are sent to deadLetters of the ActorSystem. I recommend you to check the configuration you provided for the logging of dead letters. If the file forum.conf you provided is your complete configuration file for Akka, you may want to customize some additional settings. See the page Logging of Dead Letters and Stopping actors on Akka's website. For instance, you could have a section like this:
akka {
# instead of System.out.println(conf);
log-config-on-start = on
# Max number of dead letters to log
log-dead-letters = 10
log-dead-letters-during-shutdown = on
}
Instead of using System.out.println() to log/debug, it is more convenient to set up a dedicated logger for each Actor that provides you additional information such as dispatchers, Actor name, etc. If your are interested, have a look to the Logging page.
Use some custom immutable message objects instead of systematic Strings. At first, it may seem painful to have to declare new additional classes but in the end it helps to better design complex behaviors and it's more readable. For instance, an actor A can answer to a RequestMsg coming from an actor B with an AnswerMsg or a custom ErrorMsg. Then, for your actor B, you will end up with the following onReceive() method:
#Override
public void onReceive(Object message) {
if (message instanceof AnswerMsg) {
// OK
AnswerMsg answerMsg = (AnswerMsg) message;
// ...
}
if (message instanceof ErrorMsg) {
// Not OK
ErrorMsg errorMsg = (ErrorMsg) message;
// ...
}
else {
// Unexpected behaviour, log it
log.error("Error, received " + message.toString() + " object.")
}
}
I hope that these resources will be useful for you.
Have a happy Akka programming! ;)
Is there a way to detect if Google Glass is connected to the internet at runtime? For instance, I often get the message "Can't reach Google right now" when using voice input in my app. Instead, I would like to preemptively intercept the condition that would cause that message and use default values rather than ask for voice input. After searching for a while, the only thing I could find was a solution to the same question for Android in general:
private boolean isConnected() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
I tried using this for my Glassware but it doesn't seem to work (I turned off the wifi and data but isConnected() still returns true even though I get the "Can't reach Google right now" message). Does anyone know if the GDK has a way to do this? Or should something similar to the above method work?
EDIT: Here's my eventual solution, based partially on the answer by EntryLevelDev below.
I had to use a background thread to use HTTP GET requests to avoid getting a NetworkOnMainThreadException, so I decided to have it run every few seconds and update a local isConnected variable:
public static boolean isConnected = false;
public boolean isDeviceConnectedToInternet() {
return isConnected;
}
private class CheckConnectivityTask extends AsyncTask<Void, Boolean, Boolean> {
protected Boolean doInBackground(Void... voids) {
while(true) {
// Update isConnected variable.
publishProgress(isConnected());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* Determines if the Glassware can access the internet.
* isNetworkAvailable() is used first because there is no point in executing an HTTP GET
* request if ConnectivityManager and NetworkInfo tell us that no network is available.
*/
private boolean isConnected(){
if (isNetworkAvailable()) {
HttpGet httpGet = new HttpGet("http://www.google.com");
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 3000);
HttpConnectionParams.setSoTimeout(httpParameters, 5000);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
try{
Log.d(LOG_TAG, "Checking network connection...");
httpClient.execute(httpGet);
Log.d(LOG_TAG, "Connection OK");
return true;
}
catch(ClientProtocolException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
Log.d(LOG_TAG, "Connection unavailable");
} else {
// No connection; for Glass this probably means Bluetooth is disconnected.
Log.d(LOG_TAG, "No network available!");
}
return false;
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
Log.d(LOG_TAG, String.format("In isConnected(), activeNetworkInfo.toString(): %s",
activeNetworkInfo == null ? "null" : activeNetworkInfo.toString()));
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
protected void onProgressUpdate(Boolean... isConnected) {
DecisionMakerService.isConnected = isConnected[0];
Log.d(LOG_TAG, "Checking connection: connected = " + isConnected[0]);
}
}
To start it, call new CheckConnectivityTask().execute(); (probably from onCreate()). I also had to add these to my Android.manifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
If Glass connects to a phone with Bluetooth, your method returns true even when your phone has no WiFi and data connection.
I guess it's a correct behavior. getActiveNetworkInfo is more about a connection via available interfaces. It's not really about connection to the internet. It's like connecting to a router doesn't mean you connect to the internet.
NOTE (from the doc):
getActiveNetworkInfo returns
"a NetworkInfo object for the current default network or null if no network default network is currently active"
To check the internet connection, you might try ping Google instead though I think there might be a better way to check.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
#Override
public void run() {
Log.v(MainActivity.class.getSimpleName(), "isGoogleReachable : "
+ isGoogleReachable());
}
}).start();;
}
private boolean isGoogleReachable() {
try {
if (InetAddress.getByName("www.google.com").isReachable(5000)) {
return true;
} else {
return false;
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
Add this permission:
<uses-permission android:name="android.permission.INTERNET" />
EDIT:
Or you could try this:
public static void isNetworkAvailable(Context context){
HttpGet httpGet = new HttpGet("http://www.google.com");
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
try{
Log.d(TAG, "Checking network connection...");
httpClient.execute(httpGet);
Log.d(TAG, "Connection OK");
return;
}
catch(ClientProtocolException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
Log.d(TAG, "Connection unavailable");
}
Also see:
Detect if Android device has Internet connection
"should something similar to the above method work?"
Yes, it works fine if Bluetooth is also off.
When you have wifi and data turned off, what is the network type name that activeNetworkInfo.getTypeName() returns?
This might be a bug — can you dump as much info as possible out of the NetworkInfo object (especially the type name, DetailedState enumeration, and so forth) and file it in our issue tracker?
I have created a restful web service on netbeans that accesses a local database.
I have looked at a sample project from netbeans and they use a JPA controller.
This question may be basic, but I don't have alotted time to investigate very deeply on JPAs.
Can someone explain why the use of JPA controllers is necessary?
Also, I read this previous question,"Database table access via JPA Vs. EJB in a Web-Application" and it advises to use an EJB.
Again, can this be explained.
public class CustomerJpaController implements Serializable {
public CustomerJpaController(UserTransaction utx, EntityManagerFactory emf) {
this.utx = utx;
this.emf = emf;
}
private UserTransaction utx = null;
private EntityManagerFactory emf = null;
public EntityManager getEntityManager() {
return emf.createEntityManager();
}
public void create(Customer customer) throws PreexistingEntityException, RollbackFailureException, Exception {
EntityManager em = null;
try {
utx.begin();
em = getEntityManager();
em.persist(customer);
utx.commit();
} catch (Exception ex) {
try {
utx.rollback();
} catch (Exception re) {
throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
}
if (findCustomer(customer.getCustomerId()) != null) {
throw new PreexistingEntityException("Customer " + customer + " already exists.", ex);
}
throw ex;
} finally {
if (em != null) {
em.close();
}
}
}
I've never heard of a "JPA controller", but one typically embeds JPA code within some kind of Service class in order to handle transactions.
Stateless EJB beans are perfectly suited for this. Without them you'd have to start, commit and rollback a transaction manually, which is tedious, verbose and error prone. With EJB this becomes trivial as they transparently manage transactions for you.