#StackBounty: #java #multithreading #concurrency #java.util.concurrent #jcstress Confused by jcstress test on ReentrantReadWriteLock#tr…

Bounty: 150

I am trying to get to grips with JCStress. To ensure I understand it, I decided to write some simple tests for something that I know must be correct: java.util.concurrent.locks.ReentrantReadWriteLock.

I wrote some very simple tests to check lock mode compatibility. Unfortunately two of the stress tests are failing:

  1. X_S:
    true, true        32,768     FORBIDDEN  No default case provided, assume FORBIDDEN
    
  2. X_X:
    true, true        32,767     FORBIDDEN  No default case provided, assume FORBIDDEN
    

It seems to me that one thread should not be able to hold the read lock, whilst another thread also holds the write lock. Likewise, it should be impossible for two threads to simultaneously hold the write lock.

I realise that the problem is likely not with ReentrantReadWriteLock. I figure that I am probably making some stupid mistake in my jcstress tests with regards to the JMM and reading the state of the locks.

Unfortunately, I am not able to spot the problem. Can someone please help me understand the (stupid?) mistake that I have made?

import org.openjdk.jcstress.annotations.*;
import org.openjdk.jcstress.infra.results.ZZ_Result;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/*
 * |-----------------|
 * |  COMPATIBILITY  |
 * |-----------------|
 * |     | S   | X   |
 * |-----------------|
 * | S   | YES | NO  |
 * | X   | NO  | NO  |
 * |-----------------|
 */
public class ReentrantReadWriteLockBooleanCompatibilityTest {

    @State
    public static class S {
        public final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

        public boolean shared() {
            return lock.readLock().tryLock();
        }

        public boolean exclusive() {
            return lock.writeLock().tryLock();
        }
    }

    @JCStressTest
    @Outcome(id = "true, true", expect = Expect.ACCEPTABLE, desc = "T1 and T2 are both acquired S")
    public static class S_S {
        @Actor
        public void actor1(S s, ZZ_Result r) { r.r1 = s.shared(); }
        @Actor
        public void actor2(S s, ZZ_Result r) { r.r2 = s.shared(); }
    }

    @JCStressTest
    @Outcome(id = "true, false", expect = Expect.ACCEPTABLE, desc = "T1 acquired S, and T2 could not acquire X")
    @Outcome(id = "false, true", expect = Expect.ACCEPTABLE, desc = "T2 acquired X, and T1 could not acquire S")
    public static class S_X {
        @Actor
        public void actor1(S s, ZZ_Result r) { r.r1 = s.shared(); }
        @Actor
        public void actor2(S s, ZZ_Result r) { r.r2 = s.exclusive(); }
    }

    @JCStressTest
    @Outcome(id = "true, false", expect = Expect.ACCEPTABLE, desc = "T1 acquired X, and T2 could not acquire S")
    @Outcome(id = "false, true", expect = Expect.ACCEPTABLE, desc = "T2 acquired S and T1 could not acquire X")
    public static class X_S {
        @Actor
        public void actor1(S s, ZZ_Result r) { r.r1 = s.exclusive(); }
        @Actor
        public void actor2(S s, ZZ_Result r) { r.r2 = s.shared(); }
    }

    @JCStressTest
    @Outcome(id = "true, false", expect = Expect.ACCEPTABLE, desc = "T1 acquired X, and T2 could not acquire X")
    @Outcome(id = "false, true", expect = Expect.ACCEPTABLE, desc = "T2 acquired X and T1 could not acquire X")
    public static class X_X {
        @Actor
        public void actor1(S s, ZZ_Result r) { r.r1 = s.exclusive(); }
        @Actor
        public void actor2(S s, ZZ_Result r) { r.r2 = s.exclusive(); }
    }
}

I did try asking about this on the jcstress-dev but never received a response – http://mail.openjdk.java.net/pipermail/jcstress-dev/2018-August/000346.html. Apologies for cross-posting, but I need help with this, and so I am reposting to StackOverflow in the hope of getting attention from a larger audience.


Get this bounty!!!

#StackBounty: #java #spring #multithreading #spring-mvc Java/Spring MVC: provide request context to child threads

Bounty: 150

I have the Problem, that I want to outsource some processes of my Spring WebMVC application into separate Threads. That was easy enough and works, until I want to use a class, userRightService, which uses the global request. That’s not available in the threads, and we get a problem, that’s pretty much understandable.

This is my Error:

java.lang.RuntimeException:
org.springframework.beans.factory.BeanCreationException: Error creating bean
with name 'scopedTarget.userRightsService': Scope 'request' is not active
for the current thread; consider defining a scoped proxy for this bean if
you intend to refer to it from a singleton; nested exception is 
java.lang.IllegalStateException: Cannot ask for request attribute - 
request is not active anymore!

Okay, clear enough. I am trying to keep the request context by implementing this solution:

How to enable request scope in async task executor

This is my runnable class:

@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class myThread implements Runnable {

private RequestAttributes context;

  public DataExportThread(RequestAttributes context) {
    this.context = context;
    this.dataExportTask = dataExportTask;
  }

  public void run() {
    RequestContextHolder.setRequestAttributes(context);

And this where it gets spawned:

final DataExportThread dataExportThread = 
   new myThread(RequestContextHolder.currentRequestAttributes());

final Thread thread = new Thread(myThread);
thread.setUncaughtExceptionHandler((t, e) -> {...});
thread.start();

As far as I understood, we store the currentRequestAttributes in the thread and then, when running, we restore them currentRequestAttributes… sounded solid to me, but the error is still there. I think I made some mistake adapting the solution for my case. maybe someone can help me finding the error.

Before I went through a lot of stackoverflow-threads with different solutions (see below), so I could try something else next, but this one seemed the clearest and simplest to me, so I hope someone could help me finding the mistake in the implementation or explain why it’s the wrong approach.

I already tried this one without success:

If it’s matters:

<org.springframework-version>4.3.4.RELEASE</org.springframework-version>

BTW: I know that it would be better to restructure the application in a way, that the request is not needed in the thread but that’s very complicated in that case and I really hope I could avoid this.

Edit1:

The Bean which can not be created in the thread starts like this:

@Service("userRightsService")
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserRightsService {

Edit2:

I also tried this one:

But context is always empty…


Get this bounty!!!

#StackBounty: #java #design-patterns Using visitor pattern instead of casting

Bounty: 100

I make regular use of the visitor pattern in my code. When a class hierarchy has a visitor implemented, I use it as an alternative to instanceof and casting. However it leads to some pretty awkward code which I’d like to improve.

Consider the contrived case:

interface Animal {
    void accept(AnimalVisitor visitor);
}

class Dog implements Animal {
    void accept(AnimalVisitor visitor) {
        visitor.visit(this);
    }
}

class Cat implements Animal {
    void accept(AnimalVisitor visitor) {
        visitor.visit(this);
    }
}

interface AnimalVisitor {
    default void visit(Cat cat) {};
    default void visit(Dog dog) {};
}

In the majority of cases, to do something specific to dogs only (for example) I implement a visitor that implements the logic in its visit method – just as the pattern intends.

There are case, however, in which I want to return an optional dog from the visitor to use outside.

In these case I end up with some pretty ugly code:

List<Dog> dogs = new ArrayList<>();
animal.accept(new AnimalVisitor() {
    void visit(Dog dog) {
        dogs.add(dog);
    }
}
Optional<Dog> possibleDog = dogs.stream().findAny();

I can’t assign possibleDog directly inside the visitor because it’s not a final variable, hence the list.

This is pretty ugly and inefficient just to get around requirement for effective finality. I’d be interested in ideas of alternatives.

Alternatives I’ve considered:

Turning the visitor into a generic which can be given a return value

interface Animal {
    <T> T accept(AnimalVisitor<T> visitor);
}

interface AnimalVisitor <T> {
    default Optional<T> visit(Dog dog) { return Optional.empty(); }
    default Optional<T> visit(Cat cat) { return Optional.empty(); }
}

Creating an abstract visitor that contains most of the code and can be trivial extended to set the optional directly

abstract class AnimalCollector implements AnimalVisitor <T> {
    private Optional<T> result = Optional.empty;

    protected void setResult(T value) {
        assert !result.isPresent();
        result = Optional.of(value);
    }

    public Optional<T> asOptional() {
        return result;
    }
}

Use a stream builder instead of a list

Stream.Builder<Dog> dogs = Stream.builder();
animal.accept(new AnimalVisitor() {
    void visit(Dog dog) {
        dogs.accept(dog);
    }
}
Optional<Dog> possibleDog = dogs.build().findAny();

But I don’t find these particularly elegant. They involve a lot of boilerplate just to implement basic asA logic. I tend to use the second solution in my code to keep the usage clean. Is there a simpler solution I’m missing?

Just to be clear, I’m not that interested in answers with some variant of “use instanceof and casts”. I realise it would work in this trivial case but the situations I’m considering have quite complex use of visitors that include visiting composites and delegates which make casting impractical.


Get this bounty!!!

#StackBounty: #java #php #xml #encryption #soap WSSE – XML SOAP security and key encryption and storing (EncryptedData/EncryptedKey)

Bounty: 300

I have now spent the last couple of days to find documentation about this..

I need to send a XML via SOAP with the WSSE security header, but don’t know how to encrypt and store the encrypted keys

Here is an example

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1">
            <xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EK-1B758D26C51BFCD86614340101135741">
                <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
                <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                    <wsse:SecurityTokenReference>
                        <wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">MIIDODCCAiCgAwIBAgIGAU0FlCVCMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxCYW5rIENvbm5lY3QxFTATBgNVBAsTDEJhbmsgQ29ubmVjdDEdMBsGA1UEAxMUQmFuayBDb25uZWN0IElBLXRlc3QwHhcNMTUwNDI5MTQyODI0WhcNMTgwNDI5MTQyODI0WjAcMRowGAYDVQQDExFiYW5rIGNvbm5lY3QtdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAI23KdtaRKPTFTe/A1PnsF9dpSlTiXurKmio0OCgTP9wClHwync3JsInRwGTooA20P9zWobUnEFbEiAgRVYCxuYoldRE6NLhSC854/YTjMBeevH1TNa38lpavGiI4UwFhg70U9/JuYs21hoFyzVfaWlVfOkAMm1U/n4wHq6FZW461S5PY4A/UI1Mr8WgeIHU9GqMBtFvjynzq3SLenOPgdmKtyJ3V8EOU+DlgwKmDbxMVMtYNDZtoQvOWnuvlJ6ICDcqcW7OUkmwCKodjxxPvrdaPxyZDhT7h4FgRtrAOS8qR6L7x9D4ZIoxOMPudGvr99OSb4KVtaAEt/R7hKxG3OsCAwEAAaNCMEAwHwYDVR0jBBgwFoAU680YSkZnx1IaJAmI49LlTGiia0wwHQYDVR0OBBYEFMaWOY7Vf/iB3WVA96j5kRtbF8prMA0GCSqGSIb3DQEBCwUAA4IBAQAJ+bssSFWE6KsYT7HSDKag4Eot7yNGMY4Don/MilDnOREdu20QUS131DKrSkpBQiCXbyRUQjUoun4yue0EG+rlG3QUIlNNdJ4KZJB+dTYdLUV7XTYJNPimKAmoZ+PFNvT1eGgWcMT+MbTfpk0mw0V8IprYGa8UPchd6vtSVwpbTcPc/F4bgUTlm/V+FG4bQS61gF0koj0DEZjzat7CBHpozRgfRlXgwu26vnhWGc99uKH4GAKN4JpqPi/6Yz+7iQNJUC3yeezgBxFrIXuLpkBZSP4zunf9VxsICnxkFUXOTuYBdcbhPNzqMknD5ijFcFRZITwdv7x3uJGLkM7iUfBp</wsse:KeyIdentifier>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
                <xenc:CipherData>
                    <xenc:CipherValue>af9+FhA91ytLwjeRvTYJsRCkhjHmAQGwqYwMBoNZBn7BZhF/a6EUpM9ByarVhx1SRCpjW5fb8tBVuJO1ZkjfTUZ5EAh/oDLbkmwPdSAAVzmAURHwCq3XQgMZV3lAczlLnPamxjjZBCGqxvAmBo1CvFFPC4AcBedqY92mP8XGyVHpS7JYKOxqXK2vUA1by7371x+Mu0aoS2zJPyPLa1IPwOYgR9qicmWz1RNPiEVA8ZBCN0NRyg7FLJxdUcE81z+1SjButBo2j3qcwkNcecHzZAnweY+LSWp3H5JA3WNzUHUuvFHEaPzT5jd7fUI16xo8NLK8/Rd8Eq/zDD+T3baeVQ==</xenc:CipherValue>
                </xenc:CipherData>
                <xenc:ReferenceList>
                    <xenc:DataReference URI="#ED-1B758D26C51BFCD86614340101135852"/>
                </xenc:ReferenceList>
            </xenc:EncryptedKey>
        </wsse:Security>
        <technicalAddress xmlns="http://example.com/schema/2014" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#"/>
        <activationHeader xmlns="http://example.com/schema/2014" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
            <organisationIdentification>
                <mainRegistrationNumber>8079</mainRegistrationNumber>
                <isoCountryCode>DK</isoCountryCode>
            </organisationIdentification>
            <functionIdentification>112233445566778899</functionIdentification>
            <erpInformation/>
            <endToEndMessageId>d28b6a7dad414014a59029ef1a7e84d4</endToEndMessageId>
            <createDateTime>2015-06-11T10:08:33.258+02:00</createDateTime>
        </activationHeader>
    </soap:Header>
    <soap:Body>
        <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-1B758D26C51BFCD86614340101135852" Type="http://www.w3.org/2001/04/xmlenc#Content">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
                    <wsse:Reference URI="#EK-1B758D26C51BFCD86614340101135741"/>
                </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData>
                <xenc:CipherValue>dTSVuEJ90OYguQOsOz2ZtcE2mybwuvVl19pp7/e5yuvNygx3w5v+prpEvbjYLauiIAB3lrVDK2astJeYJGnDbaVJVeU0YqH5ItYVn7Wz36jJM52KB+UNbYo8EdTKYjsZuADzH+tAoA+pwYxGBXMEQctNI+C711HgP2hbpHNYOG7nAMOIrP/0B3FCy+st+9CbYlwAEENreTYunEEA41hciFnWCsIx0el7OeuiA6V51fAmvrF19RPNKwaptvbvmVdKj//RQ/0U1kRny16mDnFfX92bI3HBQm4XJA0nEfSvio7EUAAdhe77GMfu7+JELqXNowPGPLlvrbCFYnQhxGRITHtTIEbtJA6MKtBzHgjtw5pt7oWxKgGUnaJTfOPOSv43RLFGggkT/+gTjnZOagu8hhXp0x5HXJuZzw90aIS3jAfSPDc2ivct4WhWk0wcuQyC2rAh4I7gtiR+LqJJGqvucw4S+NR95FunKHKEW4yasKW1oU31/rRbp4Bmwo6BPsQlxnaSHPtk68IVkYDBslz1A5gOP+M/Iam2WI02y6sE/7aAH1ruN3pZlVuYFc3JDNHOPOvevP110d60lroknGdc9vxcFfj48OCKw/8Ed6tiXtAvk0Qu9Qt4ZyLUoPKIWEqjdLjwVadTDJQFAxRptNgiCos7s0czadUu7FNCRxfndjDxhA7trvys44ufEyK++YzZIgNu3r4dywNI22Nm+JZtLj+rX8ARE6FTPlxGBD0SSdXsfCfY2N1ytBBHQRnPsVaHK1p7KOhwQVbqEupcGyvaRolnymOzDLGFdS06OGYFrYXdgIbuqYtZP8QerXtUl0sWNAvvqHSPCQcpKecpMEecar+FUVwLEA+H1wzOprCMbRR+EgIboeDqQ7GxXqugkuFyvnlLDgxnaWhEhQb/5kAcQmnyUZ57MhDcUJqqQ4Cdmwrcxho1P+YqWY9yn0E86F+hl5976a/gH5KBobB84OWmgcX42eAmqpJf+8c8SuBv+7NctbQOk21aYlFEpkwSme/kG1/edtyoHQH/hF0RB1cT8g+u9S9AK2rs3s2G+Ap0U5oyY8pqJalGdZSBudE0sU4mhOV8trtx0FrN9A7pNkTcGPH25nCtyIz6rzR+DP8Mtgw5385s5ivVlDb+z74Wbh6iu7ZkVAogNTpUYU/1BxDXWJqFMkFmfziNxQ5AQqm1vGlBzXifoQkUFX1riutNphmu0Hs+7KMmMLvtW2cXmQDpkHFKVheeN4w7pBCEZ8KhZ0VTOwRZcdvrNcpYfXM13/QdTHQmCqqwgS/VvlUFz7PDn0/OKo6moUic8W6b1iEvd3kfc7QkunxoOUoJr4RwJ+PqCzN6PxQivAFA2tmDPc8qEa1PAdxTeNFoR/6dNQRojouuJq3C1LrbmGf6lQPvKi3KeKHXyjmDr7Tve+al2tcWJVr+1qEM3/XuthoiZbuTDxYUjZ2nf2fhHrmNcfvrfNxSNHVdQPp2R9Rf3eGxlRJsmRpef66VbYhOpmiH4xmq45EWiyBZmYm+tZtjsP51EDMIvdFbVRSGO/hMqURrDSsJXJeot27Iup2s0P2n/6a9k0c4SVvf/WXNN5x9JNvjU97bQNDQRfonJmo9pRYYHl1tSqNIYBK7KsMH+qr1vmiJuhrXUuL/RtOKvE9KXQ8kGoC9oF5rFn21z40ElxG5XRTASg==</xenc:CipherValue>
            </xenc:CipherData>
        </xenc:EncryptedData>
    </soap:Body>
</soap:Envelope>

First of all I have never worked with SOAP before so chances I do things wrong has pretty good odds 🙂

Have found something here, but I need more details https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#aes256-cbc

How are the iv and the key stored in CipherValue in the header?

When sending the XML request to the webservice I get this error

23-08-2018 12:50:02   General exception:Padding is invalid and cannot be removed.
23-08-2018 12:50:02   Stack trace:    at System.Security.Cryptography.CapiSymmetricAlgorithm.DepadBlock(Byte[] block, Int32 offset, Int32 count)
   at System.Security.Cryptography.CapiSymmetricAlgorithm.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
   at System.Security.Cryptography.Xml.EncryptedXml.DecryptData(EncryptedData encryptedData, SymmetricAlgorithm symmetricAlgorithm)
   at SomeClassCore.XmlSecurity.Decryptor.DecryptData(Byte[] symmetricKey)
   at SomeClassCore.SecurityServiceImpl.UnwrapRequest(ServiceRequest serviceRequest)
   at BD.BCA.MessageHandler.MessageHandler.ProcessRequest(HttpContext context)

Have searched a bit more.. Maybe the iv must be a part of the stored data. But it’s still not working? Same error as above

class Encryption {
    public function data_encrypt(string $data, string $cipher, int $key_length): Array{
        $iv     = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
        $key    = openssl_random_pseudo_bytes($key_length);

        return [
            'data'  => base64_encode($iv.openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv)),
            'key'   => $key
        ];
    }

    public function key_encrypt(string $key): string{
        $public_cert = openssl_pkey_get_public('contents of public cert');
        openssl_public_encrypt($key, $data, $public_cert, OPENSSL_PKCS1_OAEP_PADDING);
        openssl_free_key($public_cert);

        return base64_encode($data);
    }
}

$Enc = new Encryption;
$data_encrypted = $Env->data_encrypt('The message I want to encrypt', 'AES-256-CBC', 32);

//  This base64 encoded string goes to <EncryptedData>
$data_encrypted['data'];

//  This base64 encoded string goes to <EncryptedKey> in the header
$Enc->key_encrypt($data_encrypted['key']);

update

Have been in contact with the maintainer of the webservice and OAEP padding is used with the RSA encryption and PKCS7 padding is used with AES chipher..

As I can see this is also what I do?


Get this bounty!!!

#StackBounty: #java #hibernate In Hibernate why does saveOrUpdate give an exception when object already exists in database

Bounty: 50

Previously, when I was adding a entity to database with Hibernate I used to check that it hadn’t already been added. But in an effort to improve performance I forgot this check and just tried to add without checking, as I was using saveOrUpdate() it was my understanding that if Hibernate found it was already added it would just update with and changes made by my save.

But instead it fails with

18/08/2018 21.58.34:BST:Errors:addError:SEVERE: Adding Error:Database Error:Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.jthink.songlayer.MusicBrainzReleaseWrapper#95f6f584-407f-4b26-9572-bb8c6e9c580a]
java.lang.Exception
    at com.jthink.songkong.analyse.general.Errors.addError(Errors.java:28)
    at com.jthink.songkong.exception.ExceptionHandling.handleHibernateException(ExceptionHandling.java:209)
    at com.jthink.songkong.db.ReleaseCache.addToDatabase(ReleaseCache.java:394)
    at com.jthink.songkong.db.ReleaseCache.add(ReleaseCache.java:65)




@Entity
    public class MusicBrainzReleaseWrapper
    {
        @Id
        private String guid;

        @Version
        private int version;

        @org.hibernate.annotations.Index(name = "IDX__MUSICBRAINZ_RELEASE_WRAPPER_NAME")
        @Column(length = 1000)
        private String name;

        @Lob
        @Column(length = 512000)
        private String xmldata;

        public String getGuid()
        {
            return guid;
        }

        public void setGuid(String guid)
        {
            this.guid = guid;
        }

        public String getName()
        {
            return name;
        }

        public void setName(String name)
        {
            this.name = name;
        }

        public String getXmldata()
        {
            return xmldata;
        }

        public void setXmldata(String xmldata)
        {
            this.xmldata = xmldata;
        }
    }

    private static boolean addToDatabase(Release release)
        {
            Session session = null;
            try
            {
                session = HibernateUtil.beginTransaction();
                //Marshall to String
                StringWriter sw = new StringWriter();
                Marshaller m = jc.createMarshaller();
                m.marshal(release, sw);
                sw.flush();

                MusicBrainzReleaseWrapper wrapper = new MusicBrainzReleaseWrapper();
                wrapper.setGuid(release.getId());
                wrapper.setName(release.getTitle().toLowerCase(Locale.UK));
                wrapper.setXmldata(sw.toString());
                session.saveOrUpdate(wrapper);
                session.getTransaction().commit();
                MainWindow.logger.info("Added to db release:" + release.getId() + ":" + release.getTitle());
                return true;
            }
            catch (ConstraintViolationException ce)
            {
                MainWindow.logger.warning("Release already exists in db:"+release.getId()+":"+release.getTitle());
                return true;
            }
            catch(GenericJDBCException jde)
            {
                MainWindow.logger.log(Level.SEVERE, "Failed:" +jde.getMessage());
                ExceptionHandling.handleDatabaseException(jde);
            }
            catch(HibernateException he)
            {
                MainWindow.logger.log(Level.SEVERE, "Failed:" +he.getMessage());
                ExceptionHandling.handleHibernateException(he);
            }
            catch(Exception e)
            {
                MainWindow.logger.log(Level.WARNING,"Failed AddReleaseToDatabase:"+release.getId()+ ':' +e.getMessage(),e);
                throw new RuntimeException(e);
            }
            finally
            {
                HibernateUtil.closeSession(session);
            }
            return false;
        }

Used to check first before call to addToDatabase

        if(ReleaseCache.get(release.getId())==null)
        {
            addToDatabase(release)
        }        


Get this bounty!!!

#StackBounty: #java #concurrency #wrapper FutureTaskWrapper for Java

Bounty: 100

I did not like that get synchronizes every time I call it – because I may be calling it more than once. So I wrote the wrapper for the future interface which keeps not synchronized local variable for completion state and caches the result. I am very sure it is thread safe.
Please have a look:

package i;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class FutureTaskWrapper<V> implements RunnableFuture<V> {

    private FutureTask<V> localFuture;
    private V result;
    //this one is not synchronized on purpose. It does not have to be.
    //It will either use wrapped class' done mechanism or eventually will     update and it will use cached result.
    private boolean done = false;


    public FutureTaskWrapper(FutureTask<V> instance) {
        localFuture = instance;
    }

    @Override
    public void run() {
        localFuture.run();
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        return localFuture.cancel(mayInterruptIfRunning);
    }

    @Override
    public boolean isCancelled() {
        return localFuture.isCancelled();
    }

    @Override
    public boolean isDone() {
        if (done) {
            return true;
        } else {
            return localFuture.isDone();
        }
    }

    @Override
    public V get() throws InterruptedException, ExecutionException {
        if (done) {
            System.out.println("using cached version.");
            return result;
        } else {
            System.out.println("using version version from future.");
            result = localFuture.get();
            done = true;
            return result;
        }
    }

    @Override
    public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        if (done) {
            System.out.println("using cached version.");
            return result;
        } else {
            System.out.println("using version version from future.");
            result = localFuture.get(timeout, unit);
            //could clean up localFuture here.
            done = true;
            return result;
        }
    }

    //main method for testing.
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        FutureTask<String> future = new FutureTask<>(() -> {
            Thread.sleep(1000L);
            return "future";
        });
        FutureTaskWrapper<String> wrapper = new FutureTaskWrapper(future);
        executor.submit(future);
        wrapper.get();
        wrapper.get();
        wrapper.get();
        wrapper.get();

        executor.shutdownNow();
    }
}


Get this bounty!!!

#StackBounty: #java #sql #sql-insert #sql-delete #jsqlparser How to convert insert sql statement to delete sql statement using JSQLParser

Bounty: 50

I want to convert insert sql statement to delete sql statement using JSQLParser, How this can be achieved ?
for example here is sample insert sql

INSERT INTO emp (empno, ename, job, sal, comm, deptno, joinedon) VALUES (4160, 'STURDEVIN', 'SECURITY GUARD', 2045, NULL, 30, TO_TIMESTAMP('2014-07-02 06:14:00.742000000', 'YYYY-MM-DD HH24:MI:SS.FF'));

post conversion to delete sql will be following

DELETE FROM emp WHERE empno=4160 AND ename='STURDEVIN' AND job='SECURITY GUARD' AND sal=2045 AND comm=NULL AND deptno=30 AND joinedon=TO_TIMESTAMP('2014-07-02 06:14:00.742000000', 'YYYY-MM-DD HH24:MI:SS.FF');

Here is code thus far

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.insert.Insert;

import java.util.List;

public class Main {

    public static void main(String[] args) {
        String insertSQL = "INSERT INTO emp (empno, ename, job, sal, comm, deptno, joinedon) VALUES (4160, 'STURDEVIN', 'SECURITY GUARD', 2045, NULL, 30, TO_TIMESTAMP('2014-07-02 06:14:00.742000000', 'YYYY-MM-DD HH24:MI:SS.FF'));";
        final Statement statement;
        try {
            statement = CCJSqlParserUtil.parse(insertSQL);
            if (statement instanceof Insert) {
                final Insert insertStatement = (Insert) statement;
                System.out.println("insertStatement: " + insertStatement);
                List<Column> columns = insertStatement.getColumns();
                for (final Column column : columns) {
                    System.out.println("column: " + column);
                }
                ItemsList itemsList = insertStatement.getItemsList();
                System.out.println("itemsList: " + itemsList);
                final Delete deleteStatement = new Delete();
                deleteStatement.setTable(insertStatement.getTable());
                System.out.println("deleteStatement: " + deleteStatement);
            }
        } catch (JSQLParserException e) {
            e.printStackTrace();
        }
    }
}

I am building this project using maven here is pom dependency.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>oracle.insert.delete.jsqlparser</groupId>
    <artifactId>oracle_from_insert_to_delete_using_JSqlParser</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>


</project>

Part of legacy code, These insert statement are written for setting up test data, I want to clean up test data automatically once test is complete. And not depend on poorly written delete statement in teardown.


Get this bounty!!!

#StackBounty: #java #python #pbkdf2 #hmacsha1 #hashlib Python equivalent of java PBKDF2WithHmacSHA1

Bounty: 50

I’m tasked with building a consumer of an API that requires an encrypted token with a seed value that is the UNIX time. The example I was shown was implemented using Java which I’m unfamiliar with, and after reading through documentation and other stack articles have been unable to find a solution.

Using the javax.crypto.SecretKey, javax.crypto.SecretKeyFactory, javax.crypto.spec.PBEKeySpec, and javax.crypto.spec.SecretKeySpec protocols, I need to generate a token similar to the below:

public class EncryptionTokenDemo {

public static void main(String args[]) {
    long millis = System.currentTimeMillis();
    String time = String.valueOf(millis);
    String secretKey = "somekeyvalue";
    int iterations = 12345;
    String iters = String.valueOf(iterations);
    String strToEncrypt_acctnum = "somevalue|" + time + "|" + iterations;

    try {

        byte[] input = strToEncrypt_acctnum.toString().getBytes("utf-8");
        byte[] salt = secretKey.getBytes("utf-8");
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        SecretKey tmp = factory.generateSecret(new PBEKeySpec(secretKey.toCharArray(), salt, iterations, 256));
        SecretKeySpec skc = new SecretKeySpec(tmp.getEncoded(), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, skc);
        byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
        int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
        ctLength += cipher.doFinal(cipherText, ctLength);
        String query = Base64.encodeBase64URLSafeString(cipherText);
        // String query = cipherText.toString();
        System.out.println("The unix time in ms is :: " + time);
        System.out.println("Encrypted Token is :: " + query);
    } catch (Exception e) {
        System.out.println("Error while encrypting :" + e);

    }

}

}

Should I be using the built-in library hashlib to implement something like this? I can’t really find documentation for implementing a PBKDF2 encryption with iterations/salt as inputs. Should I be using pbkdf2? Sorry for the vague questions, I’m unfamiliar with the encryption process and feel like even just knowing what the correct constructor would be is a step in the right direction.


Get this bounty!!!

#StackBounty: #java #jersey #jersey-client HTTP Stream dropping abnormally with java jersey client

Bounty: 50

For one of our project, we are consuming HTTP feed stream by using java jersey client

With the client Feed consuming is fine, but after the 10 mins of time, stream dropping abnormally; even though stream producer is up and running and producing the stream

This is what I tried;

import java.util.Date;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.client.Invocation.Builder;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.client.ChunkedInput;

public class StreamClient {

    private static final String BOUNDARY = "n";

    public void makeCall() {
        System.out.println("Start Time"+ new Date()) ;
        Client client = ClientBuilder.newClient();
        BasicAuth auth = new BasicAuth();
        auth.setPassword("username");
        auth.setUserName("password");
        BasicAuthentication basicAuthentication = new BasicAuthentication(auth);
        client.register(basicAuthentication);
        WebTarget target = client.target("https://localhost:7211/stream/v1/");
        Builder request = target.request(MediaType.APPLICATION_JSON);
        Response response = request.get();

        final ChunkedInput<String> chunkedInput = response.readEntity(new GenericType<ChunkedInput<String>>() {
        });

        chunkedInput.setParser(ChunkedInput.createParser(BOUNDARY));
        String chunk;
        do {
            if((chunk = chunkedInput.read()) != null) 
                System.out.println(chunk);  
        }while (chunkedInput.isClosed());
        System.out.println("End Time " + new Date());
    }

    public static void main(String[] args) {
        StreamClient client = new StreamClient();
        client.makeCall();
    }


}

If stream doesn’t drop; thread has to be within the while loop; once the stream closes then thread will come out and print sysout statement

Here the question is; why chunkedinput is closed.

Please help me with resolution;


Get this bounty!!!