Categories
discuss

What are non-container thread errors in tomcat?

In catalina.out log of my Tomcat7 I get an error caused by a third-party library that starts with:

INFO: An error occurred in processing while on a non-container thread. The connection will be closed immediately
java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)

What does it really mean that the error occurred in a non-container thread?

I tried to get a similar log message by throwing an a exception from a new Thread spawned from my application code with something like that:

new Thread(){
    @Override
    public void run() {
        Integer.parseInt("boom");
    }
}.start();

but it results in

Exception in thread "Thread-28" java.lang.NumberFormatException: For input string: "boom"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:492)
    at java.lang.Integer.parseInt(Integer.java:527)
    at ...

So the question is: What does it mean when I see a log like the one quoted on the top? What does it mean that the error occurs in a non-container thread? How can I recreate that?

Answer

What does it really mean that the error occurred in a non-container thread?

This happens when you are using JSP 3.0+ asynchronous request processing.

In asynchronous mode, the client request is received by a “container” thread that calls the Servlet’s service() method. This method (or one of the subsidiary doXxxx methods) calls startAsync() which creates a Runnable for the request and dispatches it to an Executor. This executor then processes the requests on (“non-container”) worker threads.

(A more detailed explanation of what is going on in async mode, complete with an example, can be found here.)

Anyhow, the “INFO:” message is simply saying that the original exception was thrown on the stack of one of the Executor’s worker threads. It is produced when Tomcat decides to dispatch the failed request back to a a container thread so that the request cleanup can be performed.

In your example, I suspect that the original SocketException was caused by the request processing taking so long that the client (e.g. the user’s browser) timed out the request and closed the socket. Some time later, your server tried to write the response and that failed because the connection had been closed.

How can I recreate that?

I am guessing, but you should be able to reproduce that “INFO:” message by throwing an exception in the Runnable‘s run() method. You have to use async mode of course.

Categories
discuss

AIDL service not connecting after bindService()

I am trying to develop a setup of 2 applications (service app + client app) using AIDL. I have currently a setup of 3 modules:

  • android-agent-framework (android library module holding only the AIDL file)
  • android-agent (the service)
  • android-example-client (the client)

android-agent and android-agent-framework have a dependency to the first one to get access to the interface.

Whenever the client calls bindService() it gets false as return and in the ServiceConnection the onServiceConnected() is not called. Also in the service implementation the onBind() is not called. There is no error in the logs.

Here is the code:

android-agent activity:

public class MyCompanyStartActivity extends Activity {

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.i(MyCompanyStartActivity.class.toString(), "Create MyCompanyStartActivity");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ComponentName service = startService(new Intent(this, MyCompanyRequestService.class));
        Log.i("tag", service.getClassName() + "::" + service.getPackageName());
    }

}

android-agent service:

public class MyCompanyRequestService extends Service {

@Override
public IBinder onBind(Intent intent) {
    Log.i(MyCompanyRequestService.class.toString(), "Starting SmartRest Service");
    return mBinder;
}

private final IMyCompanyRequestService.Stub mBinder = new IMyCompanyRequestService.Stub() {

    @Override
    public void sendData(String xid, String authentication, String data) throws RemoteException{
        Log.i(MyCompanyRequestService.class.toString(), "sending data: " + data);
    }
};

}

android-agent manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mycompany.android.agent" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MyCompanyStartActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Services -->
        <service
            android:name="com.mycompany.android.agent.framework.MyCompanyRequestService"
            android:process=":remote"
            android:exported="true"
            android:enabled="true">
            <intent-filter>
                <action android:name="MyCompanyRequestService"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </service>

        <!-- Permissions -->

    </application>

</manifest>

android-example-client activity:

public class ClientStarter extends Activity {

    protected IMyCompanyRequestService mycompanyRequestService = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i("tag","create client");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }
    @Override
    protected void onStart() {
        super.onStart();
        if (mycompanyRequestService == null) {
            printServices();
            Intent it = new Intent("MyCompanyRequestService");
            it.setPackage("com.mycompany.android.agent.framework");
            Log.i("tag","before binding service: " + it.getAction() + "::" + it.getPackage());
            boolean serviceBinding = getApplicationContext().bindService(it, connection, Context.BIND_AUTO_CREATE);
            Log.i("tag", "service is bound: " + serviceBinding);
        }
        Handler handler = new Handler();
        handler.postDelayed(new Runner(), 10000);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(connection);
    }

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i("service", "Service connected");
            mycompanyRequestService = IMyCompanyRequestService.Stub.asInterface(service);
            Toast.makeText(getApplicationContext(), "Service Connected", Toast.LENGTH_SHORT).show();
            Log.i("service", "Service connected");
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i("service", "Service disconnected");
            mycompanyRequestService = null;
            Toast.makeText(getApplicationContext(), "Service Disconnected", Toast.LENGTH_SHORT).show();
            Log.i("service", "Service disconnected");
        }
    };

    private void printServices() {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            Log.d("service", service.service.getClassName());
        }
    }

    private class Runner implements Runnable {

        @Override
        public void run() {
            Log.i("tag","starting");
            LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            Location loc;
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                Log.e(ClientStarter.class.toString(), "Error", e);
            }            while(true) {
                try {
                    if (mycompanyRequestService != null) {
                        loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        Log.i(ClientStarter.class.toString(), loc.getLatitude() + " - " + loc.getLongitude() + " - " + loc.getAltitude());
                        mycompanyRequestService.sendData("test", "auth", String.valueOf(loc.getLatitude()) + "," + String.valueOf(loc.getLongitude()) + "," + String.valueOf(loc.getAltitude()));
                    } else {
                        Log.i(ClientStarter.class.toString(), "service not yet available");
                    }
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    Log.e(ClientStarter.class.toString(), "Error", e);
                } catch (RemoteException e) {
                    Log.e(ClientStarter.class.toString(), "Error", e);
                }
            }
        }


    }

}

The printServices() call before trying to bind the service actually lists the service so it is running.

The log does not contain any errors and the client is in the end running in the loop but the service is still null.

Maybe someone encountered a similar issue before.

Answer

After going another round through all files I found my mistake.

I needed to change:

Intent it = new Intent("MyCompanyRequestService");
it.setPackage("com.mycompany.android.agent.framework");

to:

Intent it = new Intent("MyCompanyRequestService");
it.setPackage("com.mycompany.android.agent");

The package of the Intent needs to match the package of the app and not the package of the service.

Categories
discuss

Access classpath dependencies defined in buildscript block in applied external-script

My original goal was to be able to use classpath dependencies defined in buildscript in build.gradle, inside a script that was imported into build.gradle using apply from:. However, the external script didn’t compile since the classes could not be resolved. After researching the issue, I found out that the logic needs to be duplicated and so I thought I would extract buildscript into a separate file. Then I would be able to apply that inside build.gradle and also inside the external script.

I didn’t even get past successfully applying the external buildscript file from build.gradle, let alone applying it from the external script. I’ve tried multiple things, but it seems like I always end up with one of two problems no matter what I try: either properties from gradle.properties cannot be used, or the plugin cannot be found (even though the classpath dependency has been defined).

Currently my gradle/buildscript.gradle file looks like this:

buildscript {
    repositories {
        maven { url "http://some.url.com" }
    }

    dependencies {
        classpath "my.gradle.plugin:gradle-plugin:1.0.0"
        classpath "my.library:my-library:$libraryVersion"
    }
}

libraryVersion has been defined in gradle.properties. My build.gradle is as follows:

buildscript {
    apply from: "gradle/buildscript.gradle"
}

apply plugin: 'my.gradle.plugin.PluginClass'

When I do this, gradle complains that it cannot find a plugin with id my.gradle.plugin.PluginClass. I tried removing the quotes, and I also trying project.plugin.apply(...) using the plugin’s FQN with and without quotes; both of these caused gradle to error out with a message saying that it could not find the property my on the root project.

I also tried:

buildscript {
    apply from: "gradle/buildscript.gradle", to: buildscript
}

apply plugin: 'my.gradle.PluginClass'

But this causes another error where gradle complains that it cannot resolve libraryVersion in gradle/buildscript.gradle. So I then tried this:

buildscript {
    ext.libraryVersion = "1.0.1"

    repositories {
        maven { url "http://some.url.com" }
    }

    dependencies {
        classpath "my.gradle.plugin:gradle-plugin:1.0.0"
        classpath "my.library:my-library:$libraryVersion"
    }
}

Which causes another error, where gradle says that there is no such property ext on buildscript. I understand that this is because there really is no “project” to speak of yet, since buildscript is compiled separately. Then I changed my buildscript block in build.gradle back to:

buildscript {
    apply from: "gradle/buildscript.gradle"
}

Now I don’t get the ext error, but I still get an error saying that it cannot find the plugin with the specified id.

I cannot hardcode libraryVersion inside buildscript, because I need it as a compile-time dependency in build.gradle and I’d rather not have to maintain it in two places.

This is extremely confusing and frustrating, because the following buildscript block works fine by itself in build.gradle:

buildscript {
    ext.libraryVersion = "1.0.1"

    repositories {
        maven { url "http://some.url.com" }
    }

    dependencies {
        classpath "my.gradle.plugin:gradle-plugin:1.0.0"
        classpath "my.library:my-library:$libraryVersion"
    }
}

apply plugin: 'my-plugin-id' //No need to use FQN

dependencies {
    compile "my.library:library-version:$libraryVersion"
}

The reason I tried to split out the buildscript block is because I have a file other.gradle that has some custom tasks that use classes from my.library:

import my.library.SomeThing

task customTask(type: DefaultTask) {
    //does something with SomeThing
}

But when I leave the buildscript block in build.gradle and apply the other file like so:

buildscript {
    ext.libraryVersion = "1.0.1"

    repositories {
        maven { url "http://some.url.com" }
    }

    dependencies {
        classpath "my.gradle.plugin:gradle-plugin:1.0.0"
        classpath "my.library:my-library:$libraryVersion"
    }
}

apply plugin: 'my-plugin-id' //No need to use FQN

dependencies {
    compile "my.library:my-library:$libraryVersion"
}

apply from: 'gradle/other.gradle'

I get an error from gradle saying that it cannot resolve the class my.library.SomeThing. I figured I could solve this and avoid duplication by having a common buildscript file that I could then apply in both build.gradle and other.gradle.

I created a custom plugin inside buildSrc to configure the project the way I wanted it, only to end up with a more complicated way to fail with the same result. The root cause was the same: there was no way to expose classpath dependencies to external scripts.

Is there comprehensive documentation regarding this sorts of behavior? Everything about this violates the principle of least-surprise. I would expect a buildscript block that is being used in build.gradle to “just work” when I move it to another file.

The semantics of apply with respect to buildscript blocks is not clear. In addition, the semantics of buildscript itself when it appears in an external file are not clear either – there is a marked variation in behavior, especially with respect to plugins and external properties.

What is the best way to deal with this?

Answer

This is a bit of a rant, but there is also a solution. I was able to solve this without using a separate buildscript file, but the workaround is unbelievably hackish. I think it’s a major downside that you cannot share buildscript dependencies across external scripts.

The problem is that there is no semantic consistency because behavior seems to be dependent on how you decide to organize/modularize your build-logic. If this is a known problem, it needs to be specifically called out in the documentation somewhere – the only way I’ve been able to find mentions of this sort of surprising behavior is from gradle’s own forums or from StackOverflow. I don’t think it is unreasonable to expect a build which works with discrete units of build-logic in a single file, to also work when those discrete units are split across multiple files. Build logic shouldn’t vary based on how you have decided to organize your files, as long as the semantics are consistent.

I understand that there may be technical limitations, but having builds break just because you moved logic from one file into another file is abstraction leakage because now I am required to know details and intricacies of doing so, beyond what one should be reasonably expected to know. I wouldn’t even mind if this was explicitly and specifically called out, along with solutions/workarounds to bridge the disparity in semantics. However, current documentation regarding organizing build-logic mentions none of these caveats; it only documents the happy path.

/rant

So here’s the solution. I saved a reference to the class itself by using extensions:

import my.library.SomeThing
import my.library.SomeOtherThing

buildscript {
    ext.libraryVersion = "1.0.1"

    repositories {
        maven { url "http://some.url.com" }
    }

    dependencies {
        classpath "my.gradle.plugin:gradle-plugin:1.0.0"
        classpath "my.library:my-library:$libraryVersion"
    }
}

apply plugin: 'my-plugin-id' //No need to use FQN

ext.SomeThing = SomeThing
ext.SomeOtherThing = SomeOtherThing

dependencies {
    compile "my.library:my-library:$libraryVersion"
}

apply from: 'gradle/other.gradle'

Then in other.gradle:

// Necessary; you can't just use ext.SomeThing in the task later because 
// it is available at compile-time, but apparently not at runtime. Although
// it does work if you use project.ext.SomeThing. However, I just found this
// to be more convenient.
def SomeThing = ext.SomeThing
def SomeOtherThing = ext.SomeOtherThing

task someTask(type: DefaultTask) {
    // You have to use def; you cannot use the actual type because
    // it is not available at compile-time. Also, since you only
    // have a class object, you cannot use "new" directly; you have to
    // create a new instance by calling newInstance() on the class object
    def someThing = SomeThing.newInstance(...)

    // If you are calling static methods you can invoke them directly
    // on the class object. Again, you have to use def if the return
    // type is something defined within my-library.
    def foo = SomeOtherThing.staticMethod(...)
}
Categories
discuss

JavaScript – merge two arrays of objects and de-duplicate based on property value

I want to update (replace) the objects in my array with the objects in another array. Each object has the same structure. e.g.

var origArr = [
  {name: 'Trump', isRunning: true},
  {name: 'Cruz', isRunning: true},
  {name: 'Kasich', isRunning: true}
];
var updatingArr = [
  {name: 'Cruz', isRunning: false},
  {name: 'Kasich', isRunning: false}
];
// desired result:
NEWArr = [
  {name: 'Trump', isRunning: true},
  {name: 'Cruz', isRunning: false},
  {name: 'Kasich', isRunning: false}
];

I’ve tried concat() & Underscore’s _.uniq function, but it always dumps the newer object & returns, essentially, the original array.

Is there a way to overwrite (replace) origArr with the objects in updatingArr — matching on the name property?

Answer

Using a double for loop and splice you can do it like so:

for(var i = 0, l = origArr.length; i < l; i++) {
    for(var j = 0, ll = updatingArr.length; j < ll; j++) {
        if(origArr[i].name === updatingArr[j].name) {
            origArr.splice(i, 1, updatingArr[j]);
            break;
        }
    }
}

Example here

Categories
discuss

Svg integration in pdf using flying saucer

I under gone a situation of converting html to pdf, Thankfully I can achieved this through flying saucer api. But My HTML consists of svg tags while converting I am unable to get the svg in pdf. It can be achieved using a Stackoverflow question and Tutorial.

What is meant by the replacedElementFactory?

ChainingReplacedElementFactory chainingReplacedElementFactory 
        = new ChainingReplacedElementFactory();
chainingReplacedElementFactory.addReplacedElementFactory(replacedElementFactory);
chainingReplacedElementFactory.addReplacedElementFactory(new SVGReplacedElementFactory());
renderer.getSharedContext().setReplacedElementFactory(chainingReplacedElementFactory);

Answer

It’s just an error in the tutorial, the line with replacedElementFactory is not needed.

Here is my working example.

Java:

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextRenderer;

public class PdfSvg {
    public static void main(String[] args) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document inputDoc =  builder.parse("svg.html");

        ByteArrayOutputStream output = new ByteArrayOutputStream();

        ITextRenderer renderer = new ITextRenderer();

        ChainingReplacedElementFactory chainingReplacedElementFactory = new ChainingReplacedElementFactory();
        chainingReplacedElementFactory.addReplacedElementFactory(new SVGReplacedElementFactory());
        renderer.getSharedContext().setReplacedElementFactory(chainingReplacedElementFactory);

        renderer.setDocument(inputDoc, "");;
        renderer.layout();
        renderer.createPDF(output);

        OutputStream fos = new FileOutputStream("svg.pdf");
        output.writeTo(fos);
    }
}

HTML:

<html>
<head>
<style type="text/css">
    svg {display: block;width:100mm;height:100mm}
</style>
</head>
<body>
    <div>
        <svg xmlns="http://www.w3.org/2000/svg">
            <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3"
                fill="red" />
        </svg>
    </div>
</body>
</html>

The ChainingReplacedElementFactory, SVGReplacedElement and SVGReplacedElementFactory comes from the tutorial.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..